From 04f92cd1330759e4bad1c0304b9e1c28e8d32d59 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Fri, 22 May 2020 14:04:11 -0700 Subject: [PATCH] add linux support for netstat -i --- README.md | 32 ++++++++++++++++ docs/parsers/netstat.md | 50 ++++++++++++++++++++++++- jc/parsers/netstat.py | 44 ++++++++++++++++++++-- jc/parsers/netstat_linux.py | 39 +++++++++++++++++++ tests/fixtures/centos-7.7/netstat-i.out | 5 +++ 5 files changed, 166 insertions(+), 4 deletions(-) create mode 100644 tests/fixtures/centos-7.7/netstat-i.out diff --git a/README.md b/README.md index c9881a07..4096cadd 100644 --- a/README.md +++ b/README.md @@ -1704,6 +1704,38 @@ $ netstat -r | jc --netstat -p # or: jc -p netstat -r "kind": "route" } ] + +$ netstat -i | jc --netstat -p # or: jc -p netstat -i +[ + { + "iface": "ens33", + "mtu": 1500, + "rx_ok": 476, + "rx_err": 0, + "rx_drp": 0, + "rx_ovr": 0, + "tx_ok": 312, + "tx_err": 0, + "tx_drp": 0, + "tx_ovr": 0, + "flg": "BMRU", + "kind": "interface" + }, + { + "iface": "lo", + "mtu": 65536, + "rx_ok": 0, + "rx_err": 0, + "rx_drp": 0, + "rx_ovr": 0, + "tx_ok": 0, + "tx_err": 0, + "tx_drp": 0, + "tx_ovr": 0, + "flg": "LRU", + "kind": "interface" + } +] ``` ### ntpq ``` diff --git a/docs/parsers/netstat.md b/docs/parsers/netstat.md index cc5e8ab1..ad4f787f 100644 --- a/docs/parsers/netstat.md +++ b/docs/parsers/netstat.md @@ -203,6 +203,38 @@ Examples: } ] + $ netstat -i | jc --netstat -p + [ + { + "iface": "ens33", + "mtu": 1500, + "rx_ok": 476, + "rx_err": 0, + "rx_drp": 0, + "rx_ovr": 0, + "tx_ok": 312, + "tx_err": 0, + "tx_drp": 0, + "tx_ovr": 0, + "flg": "BMRU", + "kind": "interface" + }, + { + "iface": "lo", + "mtu": 65536, + "rx_ok": 0, + "rx_err": 0, + "rx_drp": 0, + "rx_ovr": 0, + "tx_ok": 0, + "tx_err": 0, + "tx_drp": 0, + "tx_ovr": 0, + "flg": "LRU", + "kind": "interface" + } + ] + ## info ```python info(self, /, *args, **kwargs) @@ -275,7 +307,23 @@ Returns: "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 + "rx_ok": integer, + "rx_err": integer, + "rx_drp": integer, + "rx_ovr": integer, + "tx_ok": integer, + "tx_err": integer, + "tx_drp": integer, + "tx_ovr": integer, + "flg": string } ] diff --git a/jc/parsers/netstat.py b/jc/parsers/netstat.py index 5acb123b..75f1edcd 100644 --- a/jc/parsers/netstat.py +++ b/jc/parsers/netstat.py @@ -203,7 +203,36 @@ Examples: ] $ netstat -i | jc --netstat -p - + [ + { + "iface": "ens33", + "mtu": 1500, + "rx_ok": 476, + "rx_err": 0, + "rx_drp": 0, + "rx_ovr": 0, + "tx_ok": 312, + "tx_err": 0, + "tx_drp": 0, + "tx_ovr": 0, + "flg": "BMRU", + "kind": "interface" + }, + { + "iface": "lo", + "mtu": 65536, + "rx_ok": 0, + "rx_err": 0, + "rx_drp": 0, + "rx_ovr": 0, + "tx_ok": 0, + "tx_err": 0, + "tx_drp": 0, + "tx_ovr": 0, + "flg": "LRU", + "kind": "interface" + } + ] """ @@ -286,7 +315,6 @@ def process(proc_data): "irtt": integer, "iface": string, "metric": integer, - "network": string, "address": string, "ipkts": integer, - = null @@ -294,6 +322,15 @@ def process(proc_data): "opkts": integer, - = null "oerrs": integer, - = null "coll": integer, - = null + "rx_ok": integer, + "rx_err": integer, + "rx_drp": integer, + "rx_ovr": integer, + "tx_ok": integer, + "tx_err": integer, + "tx_drp": integer, + "tx_ovr": integer, + "flg": string } ] """ @@ -302,7 +339,8 @@ def process(proc_data): 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', 'ipkts', - 'ierrs', 'opkts', 'oerrs', 'coll'] + 'ierrs', 'opkts', 'oerrs', 'coll', 'rx_ok', 'rx_err', 'rx_drp', 'rx_ovr', + 'tx_ok', 'tx_err', 'tx_drp', 'tx_ovr'] for key in int_list: if key in entry: try: diff --git a/jc/parsers/netstat_linux.py b/jc/parsers/netstat_linux.py index d090731e..92e0ffa3 100644 --- a/jc/parsers/netstat_linux.py +++ b/jc/parsers/netstat_linux.py @@ -23,6 +23,13 @@ def normalize_route_headers(header): return header +def normalize_interface_headers(header): + header = header.lower() + header = header.replace('-', '_') + + return header + + def parse_network(headers, entry): # Count words in header # if len of line is one less than len of header, then insert None in field 5 @@ -79,6 +86,14 @@ def parse_route(headers, entry): return output_line +def parse_interface(headers, entry): + entry = entry.split(maxsplit=len(headers) - 1) + output_line = dict(zip(headers, entry)) + output_line['kind'] = 'interface' + + return output_line + + def parse_post(raw_data): # clean up trailing whitespace on each item in each entry # flags --- = null @@ -157,6 +172,7 @@ def parse(cleandata): socket = False bluetooth = False routing_table = False + interface_table = False headers = None for line in cleandata: @@ -166,6 +182,7 @@ def parse(cleandata): socket = False bluetooth = False routing_table = False + interface_table = False continue if line.startswith('Active UNIX'): @@ -173,6 +190,7 @@ def parse(cleandata): socket = True bluetooth = False routing_table = False + interface_table = False continue if line.startswith('Active Bluetooth'): @@ -180,6 +198,7 @@ def parse(cleandata): socket = False bluetooth = True routing_table = False + interface_table = False continue if line.startswith('Kernel IP routing table'): @@ -187,8 +206,18 @@ def parse(cleandata): socket = False bluetooth = False routing_table = True + interface_table = False continue + if line.startswith('Kernel Interface table'): + network = False + socket = False + bluetooth = False + routing_table = False + interface_table = True + continue + + # get headers if line.startswith('Proto'): header_text = normalize_headers(line) headers = header_text.split() @@ -199,6 +228,12 @@ def parse(cleandata): headers = header_text.split() continue + if line.startswith('Iface '): + header_text = normalize_interface_headers(line) + headers = header_text.split() + continue + + # parse items if network: raw_output.append(parse_network(headers, line)) continue @@ -215,4 +250,8 @@ def parse(cleandata): raw_output.append(parse_route(headers, line)) continue + if interface_table: + raw_output.append(parse_interface(headers, line)) + continue + return parse_post(raw_output) diff --git a/tests/fixtures/centos-7.7/netstat-i.out b/tests/fixtures/centos-7.7/netstat-i.out new file mode 100644 index 00000000..1ecc33ad --- /dev/null +++ b/tests/fixtures/centos-7.7/netstat-i.out @@ -0,0 +1,5 @@ +Kernel Interface table +Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg +docker0 1500 0 0 0 0 0 0 0 0 BMU +ens33 1500 476 0 0 0 312 0 0 0 BMRU +lo 65536 0 0 0 0 0 0 0 0 LRU