From 8be8d2393b276a9249e1c573ce19cf630f0942fd Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Fri, 22 May 2020 13:38:25 -0700 Subject: [PATCH] add netstat -i support for OSX --- jc/parsers/netstat.py | 19 +++++++++-- jc/parsers/netstat_osx.py | 40 ++++++++++++++++++++++ tests/fixtures/osx-10.14.6/netstat-i.out | 43 ++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 tests/fixtures/osx-10.14.6/netstat-i.out diff --git a/jc/parsers/netstat.py b/jc/parsers/netstat.py index ed182218..5acb123b 100644 --- a/jc/parsers/netstat.py +++ b/jc/parsers/netstat.py @@ -201,6 +201,9 @@ Examples: "kind": "route" } ] + + $ netstat -i | jc --netstat -p + """ @@ -282,7 +285,15 @@ def process(proc_data): "window": integer, "irtt": integer, "iface": string, - "metric": integer + "metric": integer, + + "network": string, + "address": string, + "ipkts": integer, - = null + "ierrs": integer, - = null + "opkts": integer, - = null + "oerrs": integer, - = null + "coll": integer, - = null } ] """ @@ -290,7 +301,8 @@ def process(proc_data): # integer changes int_list = ['recv_q', 'send_q', 'pid', 'refcnt', 'inode', 'unit', 'vendor', 'class', 'osx_flags', 'subcla', 'pcbcount', 'rcvbuf', 'sndbuf', 'rxbytes', 'txbytes', - 'route_refs', 'use', 'mtu', 'mss', 'window', 'irtt', 'metric'] + 'route_refs', 'use', 'mtu', 'mss', 'window', 'irtt', 'metric', 'ipkts', + 'ierrs', 'opkts', 'oerrs', 'coll'] for key in int_list: if key in entry: try: @@ -345,7 +357,8 @@ def parse(data, raw=False, quiet=False): or cleandata[0] == 'Registered kernel control modules' \ or cleandata[0] == 'Active kernel event sockets' \ or cleandata[0] == 'Active kernel control sockets' \ - or cleandata[0] == 'Routing tables': + or cleandata[0] == 'Routing tables' \ + or cleandata[0] == 'Name Mtu Network Address Ipkts Ierrs Opkts Oerrs Coll': import jc.parsers.netstat_osx raw_output = jc.parsers.netstat_osx.parse(cleandata) diff --git a/jc/parsers/netstat_osx.py b/jc/parsers/netstat_osx.py index 634880bd..1bd17bef 100644 --- a/jc/parsers/netstat_osx.py +++ b/jc/parsers/netstat_osx.py @@ -23,6 +23,14 @@ def normalize_route_headers(header): return header +def normalize_interface_headers(header): + header = header.lower() + header = header.replace('name', 'iface') + header = header.replace('-', '_') + + return header + + def parse_item(headers, entry, kind): entry = entry.split(maxsplit=len(headers) - 1) @@ -32,6 +40,10 @@ def parse_item(headers, entry, kind): if kind == 'network' and 'socket' in headers and 'udp' in str(entry): entry.insert(7, None) + # fixup interface records with no address field entry + if kind == 'interface' and len(entry) == 8: + entry.insert(3, None) + output_line = dict(zip(headers, entry)) output_line['kind'] = kind @@ -97,6 +109,7 @@ def parse(cleandata): active_kernel_event = False active_kernel_control = False routing_table = False + interface_table = False for line in cleandata: @@ -108,6 +121,7 @@ def parse(cleandata): active_kernel_event = False active_kernel_control = False routing_table = False + interface_table = False continue if line.startswith('Active Multipath Internet connections'): @@ -118,6 +132,7 @@ def parse(cleandata): active_kernel_event = False active_kernel_control = False routing_table = False + interface_table = False continue if line.startswith('Active LOCAL (UNIX) domain sockets'): @@ -128,6 +143,7 @@ def parse(cleandata): active_kernel_event = False active_kernel_control = False routing_table = False + interface_table = False continue if line.startswith('Registered kernel control modules'): @@ -138,6 +154,7 @@ def parse(cleandata): active_kernel_event = False active_kernel_control = False routing_table = False + interface_table = False continue if line.startswith('Active kernel event sockets'): @@ -148,6 +165,7 @@ def parse(cleandata): active_kernel_event = True active_kernel_control = False routing_table = False + interface_table = False continue if line.startswith('Active kernel control sockets'): @@ -158,6 +176,7 @@ def parse(cleandata): active_kernel_event = False active_kernel_control = True routing_table = False + interface_table = False continue if line.startswith('Routing tables'): @@ -168,8 +187,20 @@ def parse(cleandata): active_kernel_event = False active_kernel_control = False routing_table = True + interface_table = False continue + if line.startswith('Name Mtu '): + network = False + multipath = False + socket = False + reg_kernel_control = False + active_kernel_event = False + active_kernel_control = False + routing_table = False + interface_table = True + # don't continue since there is no real header row for this table + # get headers if network and (line.startswith('Socket ') or line.startswith('Proto ')): header_text = normalize_headers(line) @@ -201,6 +232,11 @@ def parse(cleandata): headers = header_text.split() continue + if interface_table and line.startswith('Name Mtu '): + header_text = normalize_interface_headers(line) + headers = header_text.split() + continue + # get items if network: raw_output.append(parse_item(headers, line, 'network')) @@ -230,4 +266,8 @@ def parse(cleandata): raw_output.append(parse_item(headers, line, 'route')) continue + if interface_table: + raw_output.append(parse_item(headers, line, 'interface')) + continue + return parse_post(raw_output) diff --git a/tests/fixtures/osx-10.14.6/netstat-i.out b/tests/fixtures/osx-10.14.6/netstat-i.out new file mode 100644 index 00000000..c91f4a93 --- /dev/null +++ b/tests/fixtures/osx-10.14.6/netstat-i.out @@ -0,0 +1,43 @@ +Name Mtu Network Address Ipkts Ierrs Opkts Oerrs Coll +lo0 16384 1580150 0 1580150 0 0 +lo0 16384 127 localhost 1580150 - 1580150 - - +lo0 16384 localhost ::1 1580150 - 1580150 - - +lo0 16384 fe80::1%lo0 fe80:1::1 1580150 - 1580150 - - +gif0* 1280 0 0 0 0 0 +stf0* 1280 0 0 0 0 0 +VHC12 0 0 0 0 0 0 +XHC1* 0 0 0 0 0 0 +XHC0* 0 0 0 0 0 0 +XHC20 0 0 0 0 0 0 +en5 1500 ac:de:48:00:11:22 140215 0 137522 721 0 +en5 1500 fe80::aede: fe80:8::aede:48ff 140215 - 137522 - - +ap1* 1500 a6:83:e7:2d:62:8f 0 0 0 0 0 +en0 1500 a4:83:e7:2d:62:8f 23300545 0 26448755 464 0 +en0 1500 kbrazil-mac fe80:a::cf9:ca6f: 23300545 - 26448755 - - +en0 1500 192.168.1 kbrazil-mac.att 23300545 - 26448755 - - +en0 1500 kbrazil-mac 2600:1700:bab0:d4 23300545 - 26448755 - - +en0 1500 kbrazil-mac 2600:1700:bab0:d4 23300545 - 26448755 - - +en0 1500 kbrazil-mac 2600:1700:bab0:d4 23300545 - 26448755 - - +en0 1500 kbrazil-mac 2600:1700:bab0:d4 23300545 - 26448755 - - +en0 1500 kbrazil-mac 2600:1700:bab0:d4 23300545 - 26448755 - - +en0 1500 kbrazil-mac 2600:1700:bab0:d4 23300545 - 26448755 - - +p2p0 2304 06:83:e7:2d:62:8f 0 0 0 0 0 +awdl0 1484 b6:1f:b7:57:a5:4f 0 0 5097 0 0 +awdl0 1484 fe80::b41f: fe80:c::b41f:b7ff 0 - 5097 - - +en1 1500 ea:00:fd:08:57:01 0 0 0 0 0 +en2 1500 ea:00:fd:08:57:00 0 0 0 0 0 +en3 1500 ea:00:fd:08:57:05 0 0 0 0 0 +en4 1500 ea:00:fd:08:57:04 0 0 0 0 0 +bridg 1500 ea:00:fd:08:57:01 0 0 0 0 0 +utun0 2000 0 0 159 0 0 +utun0 2000 kbrazil-mac fe80:12::30fe:52f 0 - 159 - - +utun1 1380 0 0 2 0 0 +utun1 1380 kbrazil-mac fe80:15::aaf6:178 0 - 2 - - +utun2 1380 0 0 2 0 0 +utun2 1380 kbrazil-mac fe80:16::ce02:efd 0 - 2 - - +utun3 1380 0 0 2 0 0 +utun3 1380 kbrazil-mac fe80:17::1188:a03 0 - 2 - - +vmnet 1500 00:50:56:c0:00:01 0 0 0 0 0 +vmnet 1500 192.168.101 192.168.101.1 0 - 0 - - +vmnet 1500 00:50:56:c0:00:08 1853 0 0 0 0 +vmnet 1500 192.168.71 192.168.71.1 1853 - 0 - -