1
0
mirror of https://github.com/kellyjonbrazil/jc.git synced 2025-06-17 00:07:37 +02:00

add netstat -r functionality for OSX

This commit is contained in:
Kelly Brazil
2020-05-22 11:09:41 -07:00
parent df1e4b414b
commit 5d0dbece93
8 changed files with 288 additions and 5 deletions

View File

@ -5,6 +5,11 @@ Usage:
Specify --netstat as the first argument if the piped input is coming from netstat
Caveats:
- Use of multiple 'l' options is not supported on OSX (e.g. 'netstat -rlll')
- Use of the 'A' option is not supported on OSX when using the 'r' option (e.g. netstat -rA)
Compatibility:
'linux', 'darwin'
@ -368,7 +373,17 @@ Returns:
"rcvbuf": integer,
"sndbuf": integer,
"rxbytes": integer,
"txbytes": integer
"txbytes": integer,
"destination": string,
"gateway": string,
"route_flags": string,
"route_refs": integer,
"use": integer,
"mtu": integer,
"netif": string,
"expire": string
}
]

View File

@ -4,6 +4,11 @@ Usage:
Specify --netstat as the first argument if the piped input is coming from netstat
Caveats:
- Use of multiple 'l' options is not supported on OSX (e.g. 'netstat -rlll')
- Use of the 'A' option is not supported on OSX when using the 'r' option (e.g. netstat -rA)
Compatibility:
'linux', 'darwin'
@ -375,14 +380,25 @@ def process(proc_data):
"rcvbuf": integer,
"sndbuf": integer,
"rxbytes": integer,
"txbytes": integer
"txbytes": integer,
"destination": string,
"gateway": string,
"route_flags": string,
"route_refs": integer,
"use": integer,
"mtu": integer,
"netif": string,
"expire": string
}
]
"""
for entry in proc_data:
# integer changes
int_list = ['recv_q', 'send_q', 'pid', 'refcnt', 'inode', 'unit', 'vendor', 'class',
'osx_flags', 'subcla', 'pcbcount', 'rcvbuf', 'sndbuf', 'rxbytes', 'txbytes']
'osx_flags', 'subcla', 'pcbcount', 'rcvbuf', 'sndbuf', 'rxbytes', 'txbytes',
'route_refs', 'use', 'mtu']
for key in int_list:
if key in entry:
try:
@ -436,7 +452,8 @@ def parse(data, raw=False, quiet=False):
or cleandata[0] == 'Active LOCAL (UNIX) domain sockets' \
or cleandata[0] == 'Registered kernel control modules' \
or cleandata[0] == 'Active kernel event sockets' \
or cleandata[0] == 'Active kernel control sockets':
or cleandata[0] == 'Active kernel control sockets' \
or cleandata[0] == 'Routing tables':
import jc.parsers.netstat_osx
raw_output = jc.parsers.netstat_osx.parse(cleandata)

View File

@ -13,6 +13,15 @@ def normalize_headers(header):
return header
def normalize_route_headers(header):
header = header.lower()
header = header.replace('flags', 'route_flags')
header = header.replace('refs', 'route_refs')
header = header.replace('-', '_')
return header
def parse_item(headers, entry, kind):
entry = entry.split(maxsplit=len(headers) - 1)
@ -82,10 +91,11 @@ def parse(cleandata):
raw_output = []
network = False
multipath = False
socket = False
reg_kernel_control = False
active_kernel_event = False
active_kernel_control = False
socket = False
routing_table = False
for line in cleandata:
@ -96,6 +106,7 @@ def parse(cleandata):
reg_kernel_control = False
active_kernel_event = False
active_kernel_control = False
routing_table = False
continue
if line.startswith('Active Multipath Internet connections'):
@ -105,6 +116,7 @@ def parse(cleandata):
reg_kernel_control = False
active_kernel_event = False
active_kernel_control = False
routing_table = False
continue
if line.startswith('Active LOCAL (UNIX) domain sockets'):
@ -114,6 +126,7 @@ def parse(cleandata):
reg_kernel_control = False
active_kernel_event = False
active_kernel_control = False
routing_table = False
continue
if line.startswith('Registered kernel control modules'):
@ -123,6 +136,7 @@ def parse(cleandata):
reg_kernel_control = True
active_kernel_event = False
active_kernel_control = False
routing_table = False
continue
if line.startswith('Active kernel event sockets'):
@ -132,6 +146,7 @@ def parse(cleandata):
reg_kernel_control = False
active_kernel_event = True
active_kernel_control = False
routing_table = False
continue
if line.startswith('Active kernel control sockets'):
@ -141,6 +156,17 @@ def parse(cleandata):
reg_kernel_control = False
active_kernel_event = False
active_kernel_control = True
routing_table = False
continue
if line.startswith('Routing tables'):
network = False
multipath = False
socket = False
reg_kernel_control = False
active_kernel_event = False
active_kernel_control = False
routing_table = True
continue
# get headers
@ -169,6 +195,11 @@ def parse(cleandata):
headers = header_text.split()
continue
if routing_table and line.startswith('Destination '):
header_text = normalize_route_headers(line)
headers = header_text.split()
continue
# get items
if network:
raw_output.append(parse_item(headers, line, 'network'))
@ -194,4 +225,8 @@ def parse(cleandata):
raw_output.append(parse_item(headers, line, 'Active kernel control socket'))
continue
if routing_table and not (line.startswith('Internet:') or line.startswith('Internet6:')):
raw_output.append(parse_item(headers, line, 'route'))
continue
return parse_post(raw_output)

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,93 @@
Routing tables
Internet:
Destination Gateway Flags Refs Use Netif Expire
default dsldevice.attlocal UGSc 85 24 en0
127 localhost UCS 0 0 lo0
localhost localhost UH 20 1266183 lo0
169.254 link#10 UCS 1 0 en0 !
192.168.1 link#10 UCS 11 0 en0 !
kellys-iphone.attl e0:33:8e:68:38:d6 UHLWIi 2 466 en0 866
kellys-mbp.attloca f0:18:98:3:d8:39 UHLWIi 2 8877 en0 187
ipad.attlocal.net 4c:56:9d:5f:b7:4c UHLWI 0 600 en0 786
mycloudex2ultra.at 0:90:a9:ed:e4:35 UHLWIi 1 265596 en0 1044
family-room-5.attl c8:d0:83:cd:e3:2d UHLWIi 1 4308 en0 391
bedroom.attlocal.n d0:3:4b:3b:28:d5 UHLWIi 1 4586 en0 36
upstairs.attlocal. 50:32:37:d7:f5:9b UHLWIi 1 6117 en0 1161
rbr50.attlocal.net 3c:37:86:15:ad:f7 UHLWI 0 16 en0 678
192.168.1.221/32 link#10 UCS 1 0 en0 !
kbrazil-mac.attloc a4:83:e7:2d:62:8f UHLWI 0 36 lo0
irobot-f5788f2e24e 50:14:79:12:42:3e UHLWI 0 0 en0 1173
victoriasiphone.at 14:60:cb:10:ec:17 UHLWI 0 54 en0 64
rbs50.attlocal.net 3c:37:86:15:dd:b3 UHLWI 0 3300 en0 952
192.168.1.254/32 link#10 UCS 1 0 en0 !
dsldevice.attlocal fc:ae:34:a1:3a:80 UHLWIir 30 69452 en0 1180
192.168.71 link#20 UC 2 0 vmnet8 !
192.168.71.160 link#20 UHLWIi 1 1708 vmnet8 !
192.168.101 link#19 UC 1 0 vmnet1 !
224.0.0/4 link#10 UmCS 2 0 en0 !
224.0.0.251 1:0:5e:0:0:fb UHmLWI 0 312 en0
239.255.255.250 1:0:5e:7f:ff:fa UHmLWI 0 9914 en0
255.255.255.255/32 link#10 UCS 0 0 en0 !
Internet6:
Destination Gateway Flags Netif Expire
default fe80::feae:34ff:fe UGc en0
default fe80::%utun0 UGcI utun0
default fe80::%utun1 UGcI utun1
default fe80::%utun2 UGcI utun2
default fe80::%utun3 UGcI utun3
localhost localhost UHL lo0
2600:1700:bab0:d40 link#10 UC en0
dsldevice6.attloca fc:ae:34:a1:3a:80 UHLWIi en0
2600:1700:bab0:d40 a4:83:e7:2d:62:8f UHL lo0
2600:1700:bab0:d40 a4:83:e7:2d:62:8f UHL lo0
2600:1700:bab0:d40 a4:83:e7:2d:62:8f UHL lo0
kbrazil-mac.attloc a4:83:e7:2d:62:8f UHL lo0
kbrazil-mac.attloc a4:83:e7:2d:62:8f UHL lo0
kbrazil-mac.attloc a4:83:e7:2d:62:8f UHL lo0
fe80::%lo0 fe80::1%lo0 UcI lo0
fe80::1%lo0 link#1 UHLI lo0
fe80::%en5 link#8 UCI en5
fe80::aede:48ff:fe ac:de:48:0:11:22 UHLI lo0
fe80::aede:48ff:fe ac:de:48:33:44:55 UHLWIi en5
fe80::%en0 link#10 UCI en0
fe80::df:eea7:d8e0 14:60:cb:10:ec:17 UHLWI en0
fe80::472:ae33:7f7 b4:18:d1:9d:bc:2d UHLWI en0
ipad.local 4c:56:9d:5f:b7:4c UHLWI en0
fe80::ced:5f18:1d1 14:60:cb:10:ec:17 UHLWI en0
kbrazil-mac.local a4:83:e7:2d:62:8f UHLI lo0
fe80::10f2:d51c:68 e0:33:8e:68:38:d6 UHLWI en0
upstairs.local 50:32:37:d7:f5:9b UHLWIi en0
fe80::1899:d8f6:dc 50:32:37:d7:f5:9b UHLWI en0
kellys-macbook-pro f0:18:98:3:d8:39 UHLWI en0
bedroom.local d0:3:4b:3b:28:d5 UHLWI en0
kellys-airport-exp 48:d7:5:f1:86:e8 UHLWI en0
hp9cb654545bb9.loc 9c:b6:54:5a:5a:7c UHLWI en0
fe80::feae:34ff:fe fc:ae:34:a1:3a:80 UHLWIir en0
fe80::%awdl0 link#12 UCI awdl0
fe80::b41f:b7ff:fe b6:1f:b7:57:a5:4f UHLI lo0
fe80::%utun0 kbrazil-mac.local UcI utun0
kbrazil-mac.local link#18 UHLI lo0
fe80::%utun1 kbrazil-mac.local UcI utun1
kbrazil-mac.local link#21 UHLI lo0
fe80::%utun2 kbrazil-mac.local UcI utun2
kbrazil-mac.local link#22 UHLI lo0
fe80::%utun3 kbrazil-mac.local UcI utun3
kbrazil-mac.local link#23 UHLI lo0
ff01::%lo0 localhost UmCI lo0
ff01::%en5 link#8 UmCI en5
ff01::%en0 link#10 UmCI en0
ff01::%awdl0 link#12 UmCI awdl0
ff01::%utun0 kbrazil-mac.local UmCI utun0
ff01::%utun1 kbrazil-mac.local UmCI utun1
ff01::%utun2 kbrazil-mac.local UmCI utun2
ff01::%utun3 kbrazil-mac.local UmCI utun3
ff02::%lo0 localhost UmCI lo0
ff02::%en5 link#8 UmCI en5
ff02::%en0 link#10 UmCI en0
ff02::%awdl0 link#12 UmCI awdl0
ff02::%utun0 kbrazil-mac.local UmCI utun0
ff02::%utun1 kbrazil-mac.local UmCI utun1
ff02::%utun2 kbrazil-mac.local UmCI utun2
ff02::%utun3 kbrazil-mac.local UmCI utun3

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,96 @@
Routing tables
Internet:
Destination Gateway Flags Refs Use Mtu Netif Expire
default 192.168.1.254 UGSc 83 24 1500 en0
127 127.0.0.1 UCS 0 0 16384 lo0
127.0.0.1 127.0.0.1 UH 18 1266231 16384 lo0
169.254 link#10 UCS 1 0 1500 en0 !
192.168.1 link#10 UCS 12 0 1500 en0 !
192.168.1.64 e0:33:8e:68:38:d6 UHLWIi 2 470 1500 en0 753
192.168.1.72 f0:18:98:3:d8:39 UHLWIi 1 8878 1500 en0 1105
192.168.1.75 4c:56:9d:5f:b7:4c UHLWIi 1 600 1500 en0 673
192.168.1.80 0:90:a9:ed:e4:35 UHLWIi 1 265604 1500 en0 931
192.168.1.88 c8:d0:83:cd:e3:2d UHLWIi 1 4310 1500 en0 278
192.168.1.89 d0:3:4b:3b:28:d5 UHLWIi 1 4588 1500 en0 1132
192.168.1.186 50:32:37:d7:f5:9b UHLWIi 1 6123 1500 en0 1181
192.168.1.216 3c:37:86:15:ad:f7 UHLWI 0 16 1500 en0 565
192.168.1.221/32 link#10 UCS 1 0 1500 en0 !
192.168.1.221 a4:83:e7:2d:62:8f UHLWI 0 36 16384 lo0
192.168.1.242 50:14:79:12:42:3e UHLWI 0 0 1500 en0 1182
192.168.1.251 14:60:cb:10:ec:17 UHLWI 0 54 1500 en0 1157
192.168.1.253 3c:37:86:15:dd:b3 UHLWI 0 3300 1500 en0 839
192.168.1.254/32 link#10 UCS 1 0 1500 en0 !
192.168.1.254 fc:ae:34:a1:3a:80 UHLWIir 29 69464 1500 en0 1200
192.168.1.255 ff:ff:ff:ff:ff:ff UHLWbI 0 4 1500 en0 !
192.168.71 link#20 UC 3 0 1500 vmnet8 !
192.168.71.160 link#20 UHLWIi 1 1708 1500 vmnet8 !
192.168.71.255 ff:ff:ff:ff:ff:ff UHLWbI 0 4 1500 vmnet8 !
192.168.101 link#19 UC 2 0 1500 vmnet1 !
192.168.101.255 ff:ff:ff:ff:ff:ff UHLWbI 0 4 1500 vmnet1 !
224.0.0/4 link#10 UmCS 2 0 1500 en0 !
224.0.0.251 1:0:5e:0:0:fb UHmLWI 0 312 1500 en0
239.255.255.250 1:0:5e:7f:ff:fa UHmLWI 0 9918 1500 en0
255.255.255.255/32 link#10 UCS 0 0 1500 en0 !
Internet6:
Destination Gateway Flags Refs Use Mtu Netif Expire
default fe80::feae:34ff:fea1:3a80%en0 UGc 7 0 1500 en0
default fe80::%utun0 UGcI 0 0 2000 utun0
default fe80::%utun1 UGcI 0 0 1380 utun1
default fe80::%utun2 UGcI 0 0 1380 utun2
default fe80::%utun3 UGcI 0 0 1380 utun3
::1 ::1 UHL 1 4513 16384 lo0
2600:1700:bab0:d40::/64 link#10 UC 2 0 1500 en0
2600:1700:bab0:d40::1 fc:ae:34:a1:3a:80 UHLWIi 12 68412 1500 en0
2600:1700:bab0:d40::39 a4:83:e7:2d:62:8f UHL 0 0 16384 lo0
2600:1700:bab0:d40:1874:4566:6499:f3d1 a4:83:e7:2d:62:8f UHL 0 0 16384 lo0
2600:1700:bab0:d40:5894:f4c5:a982:26be a4:83:e7:2d:62:8f UHL 0 0 16384 lo0
2600:1700:bab0:d40:c9de:af8a:762c:422c a4:83:e7:2d:62:8f UHL 0 0 16384 lo0
2600:1700:bab0:d40:edd2:2cbf:f03a:d14f a4:83:e7:2d:62:8f UHL 0 0 16384 lo0
2600:1700:bab0:d40:f078:690e:f0ba:dfb a4:83:e7:2d:62:8f UHL 0 0 16384 lo0
fe80::%lo0/64 fe80::1%lo0 UcI 1 0 16384 lo0
fe80::1%lo0 link#1 UHLI 0 0 16384 lo0
fe80::%en5/64 link#8 UCI 2 0 1500 en5
fe80::aede:48ff:fe00:1122%en5 ac:de:48:0:11:22 UHLI 0 0 16384 lo0
fe80::aede:48ff:fe33:4455%en5 ac:de:48:33:44:55 UHLWIi 77 826 1500 en5
fe80::%en0/64 link#10 UCI 13 0 1500 en0
fe80::df:eea7:d8e0:237a%en0 14:60:cb:10:ec:17 UHLWI 0 293 1500 en0
fe80::472:ae33:7f74:8baf%en0 b4:18:d1:9d:bc:2d UHLWI 0 2 1500 en0
fe80::c73:1ab9:79c2:c193%en0 4c:56:9d:5f:b7:4c UHLWI 0 1597 1500 en0
fe80::ced:5f18:1d1e:2d6b%en0 14:60:cb:10:ec:17 UHLWI 0 14 1500 en0
fe80::cf9:ca6f:7d7a:50a2%en0 a4:83:e7:2d:62:8f UHLI 0 0 16384 lo0
fe80::10f2:d51c:68e3:bfbb%en0 e0:33:8e:68:38:d6 UHLWI 0 656 1500 en0
fe80::1406:1bd5:a957:6df2%en0 50:32:37:d7:f5:9b UHLWI 0 2100 1500 en0
fe80::1899:d8f6:dca5:207%en0 50:32:37:d7:f5:9b UHLWI 0 4619 1500 en0
fe80::1c4d:12ea:5e57:24ad%en0 f0:18:98:3:d8:39 UHLWIi 1 8 1500 en0
fe80::1cff:a835:c99b:22c1%en0 d0:3:4b:3b:28:d5 UHLWI 0 477 1500 en0
fe80::4ad7:5ff:fef1:86e8%en0 48:d7:5:f1:86:e8 UHLWI 0 862 1500 en0
fe80::9eb6:54ff:fe5a:5a7c%en0 9c:b6:54:5a:5a:7c UHLWI 0 322 1500 en0
fe80::feae:34ff:fea1:3a80%en0 fc:ae:34:a1:3a:80 UHLWIir 7 27100 1500 en0
fe80::%awdl0/64 link#12 UCI 1 0 1484 awdl0
fe80::b41f:b7ff:fe57:a54f%awdl0 b6:1f:b7:57:a5:4f UHLI 1 0 16384 lo0
fe80::%utun0/64 fe80::30fe:52f1:103c:c66c%utun0 UcI 2 0 2000 utun0
fe80::30fe:52f1:103c:c66c%utun0 link#18 UHLI 1 0 16384 lo0
fe80::%utun1/64 fe80::aaf6:1785:571a:57a9%utun1 UcI 2 0 1380 utun1
fe80::aaf6:1785:571a:57a9%utun1 link#21 UHLI 0 0 16384 lo0
fe80::%utun2/64 fe80::ce02:efdc:708:5411%utun2 UcI 2 0 1380 utun2
fe80::ce02:efdc:708:5411%utun2 link#22 UHLI 0 0 16384 lo0
fe80::%utun3/64 fe80::1188:a032:c478:4b13%utun3 UcI 2 0 1380 utun3
fe80::1188:a032:c478:4b13%utun3 link#23 UHLI 0 0 16384 lo0
ff01::%lo0/32 ::1 UmCI 0 0 16384 lo0
ff01::%en5/32 link#8 UmCI 0 0 1500 en5
ff01::%en0/32 link#10 UmCI 0 0 1500 en0
ff01::%awdl0/32 link#12 UmCI 0 0 1484 awdl0
ff01::%utun0/32 fe80::30fe:52f1:103c:c66c%utun0 UmCI 0 0 2000 utun0
ff01::%utun1/32 fe80::aaf6:1785:571a:57a9%utun1 UmCI 0 0 1380 utun1
ff01::%utun2/32 fe80::ce02:efdc:708:5411%utun2 UmCI 0 0 1380 utun2
ff01::%utun3/32 fe80::1188:a032:c478:4b13%utun3 UmCI 0 0 1380 utun3
ff02::%lo0/32 ::1 UmCI 0 0 16384 lo0
ff02::%en5/32 link#8 UmCI 0 0 1500 en5
ff02::%en0/32 link#10 UmCI 0 0 1500 en0
ff02::%awdl0/32 link#12 UmCI 0 0 1484 awdl0
ff02::%utun0/32 fe80::30fe:52f1:103c:c66c%utun0 UmCI 0 0 2000 utun0
ff02::%utun1/32 fe80::aaf6:1785:571a:57a9%utun1 UmCI 0 0 1380 utun1
ff02::%utun2/32 fe80::ce02:efdc:708:5411%utun2 UmCI 0 0 1380 utun2
ff02::%utun3/32 fe80::1188:a032:c478:4b13%utun3 UmCI 0 0 1380 utun3

View File

@ -52,6 +52,13 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/netstat-Abn.out'), 'r', encoding='utf-8') as f:
self.osx_14_6_netstat_Abn = f.read()
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/netstat-r.out'), 'r', encoding='utf-8') as f:
self.osx_14_6_netstat_r = f.read()
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/netstat-rnl.out'), 'r', encoding='utf-8') as f:
self.osx_14_6_netstat_rnl = f.read()
# output
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/netstat.json'), 'r', encoding='utf-8') as f:
self.centos_7_7_netstat_json = json.loads(f.read())
@ -95,6 +102,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/netstat-Abn.json'), 'r', encoding='utf-8') as f:
self.osx_14_6_netstat_Abn_json = json.loads(f.read())
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/netstat-r.json'), 'r', encoding='utf-8') as f:
self.osx_14_6_netstat_r_json = json.loads(f.read())
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/netstat-rnl.json'), 'r', encoding='utf-8') as f:
self.osx_14_6_netstat_rnl_json = json.loads(f.read())
def test_netstat_centos_7_7(self):
"""
Test 'netstat' on Centos 7.7
@ -179,6 +192,18 @@ class MyTests(unittest.TestCase):
"""
self.assertEqual(jc.parsers.netstat.parse(self.osx_14_6_netstat_Abn, quiet=True), self.osx_14_6_netstat_Abn_json)
def test_netstat_r_osx_16_4(self):
"""
Test 'netstat -r' on OSX 16.4
"""
self.assertEqual(jc.parsers.netstat.parse(self.osx_14_6_netstat_r, quiet=True), self.osx_14_6_netstat_r_json)
def test_netstat_rnl_osx_16_4(self):
"""
Test 'netstat -rnl' on OSX 16.4
"""
self.assertEqual(jc.parsers.netstat.parse(self.osx_14_6_netstat_rnl, quiet=True), self.osx_14_6_netstat_rnl_json)
if __name__ == '__main__':
unittest.main()