blob: be29b8f1fcaa6f09e691061ff4a5c9d1de15d151 [file] [log] [blame]
Oleksandr Savatieievfb9f9432018-11-23 17:39:12 +01001import re
2import sys
3import subprocess
4import json
5
6
7def shell(command):
8 _ps = subprocess.Popen(
9 command.split(),
10 stdout=subprocess.PIPE
11 ).communicate()[0].decode()
12
13 return _ps
14
15
16def cut_option(_param, _options_list):
17 _option = "n/a"
18 _result_list = []
19 if _param in _options_list:
20 _index = _options_list.index(_param)
21 _option = _options_list[_index+1]
22 _l1 = _options_list[:_index]
23 _l2 = _options_list[_index+2:]
24 _result_list = _l1 + _l2
25 else:
26 _result_list = _options_list
27 return _option, _result_list
28
29
Alex Savatieiev0137dad2019-01-25 16:18:42 +010030def get_linked_devices(if_name):
31 if '@' in if_name:
32 _name = if_name[:if_name.index('@')]
33 else:
34 _name = if_name
35 _links = shell(
36 "find /sys/class/net/{}/ -type l".format(_name)
37 )
38 # there can be only one parent device
39 _lower = None
40 # can be more than one child device
41 _upper = None
42 for line in _links.splitlines():
43 _line = line.rsplit('/', 1)[1]
44 if _line.startswith("upper_"):
45 _upper = _line[6:]
46 elif _line.startswith("lower_"):
47 if not _lower:
48 _lower = []
49 _lower.append(_line[6:])
50
51 return _lower, _upper
52
53
Oleksandr Savatieievfb9f9432018-11-23 17:39:12 +010054def get_ifs_data():
55 _ifs_raw = shell('ip a')
56
57 if_start = re.compile("^[0-9]+: .*: \<.*\> .*$")
Alex Savatieiev0137dad2019-01-25 16:18:42 +010058 if_link = re.compile("^\s{4}link\/ether\ .*$")
Oleksandr Savatieievfb9f9432018-11-23 17:39:12 +010059 if_ipv4 = re.compile("^\s{4}inet\ .*$")
60
61 _ifs = {}
62 _if_name = None
63 for line in _ifs_raw.splitlines():
64 _if_data = {}
65 if if_start.match(line):
66 _tmp = line.split(':')
67 _if_name = _tmp[1].strip()
68 _if_options = _tmp[2].strip().split(' ')
Alex Savatieiev0137dad2019-01-25 16:18:42 +010069 _lower, _upper = get_linked_devices(_if_name)
Oleksandr Savatieievfb9f9432018-11-23 17:39:12 +010070 _if_data['order'] = _tmp[0]
71 _if_data['mtu'], _if_options = cut_option("mtu", _if_options)
72 _if_data['qlen'], _if_options = cut_option("qlen", _if_options)
73 _if_data['state'], _if_options = cut_option("state", _if_options)
74 _if_data['other'] = _if_options
75 _if_data['ipv4'] = {}
Alex Savatieiev0137dad2019-01-25 16:18:42 +010076 _if_data['mac'] = {}
77 _if_data['upper'] = _upper
78 _if_data['lower'] = _lower
Oleksandr Savatieievfb9f9432018-11-23 17:39:12 +010079 _ifs[_if_name] = _if_data
Alex Savatieiev0137dad2019-01-25 16:18:42 +010080 elif if_link.match(line):
81 if _if_name is None:
82 continue
83 else:
84 _tmp = line.strip().split(' ', 2)
85 _mac_addr = _tmp[1]
86 _options = _tmp[2].split(' ')
87 _brd, _options = cut_option("brd", _options)
88 _ifs[_if_name]['mac'][_mac_addr] = {}
89 _ifs[_if_name]['mac'][_mac_addr]['brd'] = _brd
90 _ifs[_if_name]['mac'][_mac_addr]['other'] = _options
Oleksandr Savatieievfb9f9432018-11-23 17:39:12 +010091 elif if_ipv4.match(line):
92 if _if_name is None:
93 continue
94 else:
95 _tmp = line.strip().split(' ', 2)
96 _ip = _tmp[1]
97 _options = _tmp[2].split(' ')
98 _brd, _options = cut_option("brd", _options)
99 # TODO: Parse other options, mask, brd, etc...
100 _ifs[_if_name]['ipv4'][_ip] = {}
101 _ifs[_if_name]['ipv4'][_ip]['brd'] = _brd
102 _ifs[_if_name]['ipv4'][_ip]['other'] = _options
103
104 return _ifs
105
106
107ifs_data = get_ifs_data()
108
Alex Savatieiev0137dad2019-01-25 16:18:42 +0100109if len(sys.argv) > 1 and sys.argv[1] == 'json':
110 sys.stdout.write(json.dumps(ifs_data))
111else:
112 _ifs = sorted(ifs_data.keys())
113 _ifs.remove("lo")
114 for _idx in range(len(_ifs)):
115 _linked = ""
116 if ifs_data[_ifs[_idx]]['lower']:
117 _linked += "lower:{}".format(
118 ','.join(ifs_data[_ifs[_idx]]['lower'])
119 )
120 if ifs_data[_ifs[_idx]]['upper']:
121 _linked += "upper:{}".format(ifs_data[_ifs[_idx]]['upper'])
122 print("{0:30} {1:18} {2:19} {3:5} {4:4} {5}".format(
123 _ifs[_idx],
124 ",".join(ifs_data[_ifs[_idx]]['mac'].keys()),
125 ",".join(ifs_data[_ifs[_idx]]['ipv4'].keys()),
126 ifs_data[_ifs[_idx]]['mtu'],
127 ifs_data[_ifs[_idx]]['state'],
128 _linked
129 ))