ns2 0.2.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ns2/__init__.py +0 -0
- ns2/core.py +0 -0
- ns2/dbus/__init__.py +0 -0
- ns2/dbus/dbus.py +13 -0
- ns2/lib/__init__.py +0 -0
- ns2/lib/accounts.py +130 -0
- ns2/lib/commands.py +32 -0
- ns2/lib/firewalld.py +167 -0
- ns2/lib/introspection/org.fedoraproject.FirewallD1.config.xml +3 -0
- ns2/lib/introspection/org.fedoraproject.FirewallD1.xml +763 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.AccessPoint.xml +106 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.AgentManager.xml +43 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Checkpoint.xml +36 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Connection.Active.xml +185 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.DHCP4Config.xml +21 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.DHCP6Config.xml +20 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.Adsl.xml +21 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.Bluetooth.xml +36 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.Bond.xml +40 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.Bridge.xml +41 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.Dummy.xml +20 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.Generic.xml +27 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.Hsr.xml +51 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.IPTunnel.xml +107 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.Infiniband.xml +31 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.Ipvlan.xml +38 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.Loopback.xml +8 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.Lowpan.xml +27 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.Macsec.xml +109 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.Macvlan.xml +39 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.Modem.xml +62 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.OlpcMesh.xml +34 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.OvsBridge.xml +21 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.OvsInterface.xml +11 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.OvsPort.xml +21 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.Ppp.xml +11 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.Statistics.xml +35 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.Team.xml +48 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.Tun.xml +65 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.Veth.xml +18 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.Vlan.xml +45 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.Vrf.xml +18 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.Vxlan.xml +139 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.WiMax.xml +109 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.WifiP2P.xml +76 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.WireGuard.xml +38 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.Wired.xml +53 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.Wireless.xml +131 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.Wpan.xml +20 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Device.xml +407 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.DnsManager.xml +40 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.IP4Config.xml +125 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.IP6Config.xml +95 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.PPP.xml +34 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.SecretAgent.xml +94 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Settings.Connection.xml +224 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.Settings.xml +233 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.VPN.Connection.xml +42 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.VPN.Plugin.xml +204 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.WiMax.Nsp.xml +35 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.WifiP2PPeer.xml +91 -0
- ns2/lib/introspection/org.freedesktop.NetworkManager.xml +598 -0
- ns2/lib/lib.py +0 -0
- ns2/lib/network_delay.py +92 -0
- ns2/lib/networking.py +528 -0
- ns2/lib/ntl.py +188 -0
- ns2/lib/pam_client.py +37 -0
- ns2/lib/ping_data_collector.py +37 -0
- ns2/lib/snmp.py +511 -0
- ns2/lib/socket.py +132 -0
- ns2/lib/socket_client.py +62 -0
- ns2/lib/systemd.py +151 -0
- ns2/lib/test.py +374 -0
- ns2/lib/udp_client.py +227 -0
- ns2/lib/udp_server.py +167 -0
- ns2/snmp/__init__.py +0 -0
- ns2/snmp/ns_dbus_service.py +38 -0
- ns2/snmp/pam_interface.py +19 -0
- ns2/snmp/snmp_interface.py +66 -0
- ns2/ui/__init__.py +0 -0
- ns2/ui/assets/NOVUS_LOGO.svg +105 -0
- ns2/ui/assets/favicon.png +0 -0
- ns2/ui/firewalld_page.py +375 -0
- ns2/ui/fpga_page.py +24 -0
- ns2/ui/login.py +65 -0
- ns2/ui/main.py +200 -0
- ns2/ui/networking_page.py +406 -0
- ns2/ui/ntp.py +105 -0
- ns2/ui/root.py +31 -0
- ns2/ui/snmp_page.py +353 -0
- ns2/ui/terminal.py +65 -0
- ns2/ui/tests_page.py +116 -0
- ns2/ui/theme.py +25 -0
- ns2/utils.py +5 -0
- ns2-0.2.6.dist-info/METADATA +78 -0
- ns2-0.2.6.dist-info/RECORD +98 -0
- ns2-0.2.6.dist-info/WHEEL +4 -0
- ns2-0.2.6.dist-info/entry_points.txt +3 -0
ns2/lib/network_delay.py
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
|
|
2
|
+
import requests
|
|
3
|
+
from bs4 import BeautifulSoup as bs
|
|
4
|
+
from datetime import datetime, timezone
|
|
5
|
+
import numpy as np
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
def calculate_last_50_jitter(delays):
|
|
9
|
+
delays = delays[-50:]
|
|
10
|
+
return np.sum(np.abs(np.diff(delays)))/(len(delays)-1)
|
|
11
|
+
|
|
12
|
+
def file_name_to_time(name):
|
|
13
|
+
timestamp_seconds = float(name.split("_")[0])
|
|
14
|
+
return datetime.fromtimestamp(timestamp_seconds, timezone.utc)
|
|
15
|
+
|
|
16
|
+
def get_latest_data(references :list[str]):
|
|
17
|
+
|
|
18
|
+
ts = {}
|
|
19
|
+
|
|
20
|
+
for r in references:
|
|
21
|
+
|
|
22
|
+
ts[r["href"]] = r["href"].split("_")[0]
|
|
23
|
+
|
|
24
|
+
return max(ts, key=ts.get)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def get_files_to_view():
|
|
28
|
+
host = "http://10.1.10.96:8000"
|
|
29
|
+
try:
|
|
30
|
+
rsp = requests.get(host, timeout=0.1)
|
|
31
|
+
soup = bs(rsp.content, "html.parser")
|
|
32
|
+
references = soup.find_all("a", href=True)
|
|
33
|
+
print(references)
|
|
34
|
+
return references
|
|
35
|
+
except Exception as e:
|
|
36
|
+
print(e)
|
|
37
|
+
raise
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def get_data_by_name(name :str):
|
|
42
|
+
host = "http://10.1.10.96:8000"
|
|
43
|
+
|
|
44
|
+
try:
|
|
45
|
+
rsp = requests.get(host+"/"+name)
|
|
46
|
+
except Exception as e:
|
|
47
|
+
print(e)
|
|
48
|
+
sys.exit()
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
lines = rsp.content.decode('utf-8').splitlines()
|
|
53
|
+
|
|
54
|
+
ts = []
|
|
55
|
+
delays = []
|
|
56
|
+
for i, line in enumerate(lines):
|
|
57
|
+
if i != 0:
|
|
58
|
+
values = line.split(",")
|
|
59
|
+
ts.append(float(values[0]))
|
|
60
|
+
delays.append(float(values[1]))
|
|
61
|
+
|
|
62
|
+
return file_name_to_time(name), ts, delays
|
|
63
|
+
|
|
64
|
+
def get_network_delay_data_locally():
|
|
65
|
+
|
|
66
|
+
host = "http://10.1.10.96:8000"
|
|
67
|
+
|
|
68
|
+
try:
|
|
69
|
+
rsp = requests.get(host)
|
|
70
|
+
except Exception as e:
|
|
71
|
+
print(e)
|
|
72
|
+
sys.exit()
|
|
73
|
+
|
|
74
|
+
#rsp = requests.get(host)
|
|
75
|
+
soup = bs(rsp.content, "html.parser")
|
|
76
|
+
|
|
77
|
+
references = soup.find_all("a", href=True) #["href"]
|
|
78
|
+
file_name = get_latest_data(references)
|
|
79
|
+
rsp = requests.get(host+"/"+file_name)
|
|
80
|
+
|
|
81
|
+
lines = rsp.content.decode('utf-8').splitlines()
|
|
82
|
+
|
|
83
|
+
ts = []
|
|
84
|
+
delays = []
|
|
85
|
+
for i, line in enumerate(lines):
|
|
86
|
+
if i != 0:
|
|
87
|
+
values = line.split(",")
|
|
88
|
+
ts.append(float(values[0]))
|
|
89
|
+
delays.append(float(values[1]))
|
|
90
|
+
|
|
91
|
+
return file_name_to_time(file_name), ts, delays
|
|
92
|
+
|
ns2/lib/networking.py
ADDED
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
|
|
2
|
+
from dataclasses import asdict, field
|
|
3
|
+
from typing import List, Optional
|
|
4
|
+
from nicegui import ui, app, binding
|
|
5
|
+
|
|
6
|
+
from dbus_next.signature import Variant
|
|
7
|
+
from dbus_next.errors import DBusError
|
|
8
|
+
from dbus_next.aio.proxy_object import ProxyInterface
|
|
9
|
+
from dbus_next.aio import MessageBus
|
|
10
|
+
from dbus_next import Message
|
|
11
|
+
|
|
12
|
+
from ns.lib.firewalld import formatListToString
|
|
13
|
+
from ns.utils import INTROSPECTION_DIR
|
|
14
|
+
|
|
15
|
+
# ====================================================================
|
|
16
|
+
# data classes
|
|
17
|
+
# ====================================================================
|
|
18
|
+
|
|
19
|
+
class ConnectionDetails:
|
|
20
|
+
Id: Optional[str] = ''
|
|
21
|
+
Permissions: Optional[list[str]] = None
|
|
22
|
+
Timestamp: Optional[int] = 0
|
|
23
|
+
Type: Optional[str] = ''
|
|
24
|
+
Uuid: Optional[str] = ''
|
|
25
|
+
|
|
26
|
+
@binding.bindable_dataclass
|
|
27
|
+
class IpAddress:
|
|
28
|
+
Address: Optional[str] = None
|
|
29
|
+
Prefix: Optional[int] = None
|
|
30
|
+
|
|
31
|
+
@binding.bindable_dataclass
|
|
32
|
+
class DnsServer:
|
|
33
|
+
Server: Optional[str] = ''
|
|
34
|
+
|
|
35
|
+
@binding.bindable_dataclass
|
|
36
|
+
class IpRoute:
|
|
37
|
+
Dest: Optional[str] = None
|
|
38
|
+
Prefix: Optional[int] = None
|
|
39
|
+
NextHop: Optional[str] = None
|
|
40
|
+
Metric: Optional[int] = None
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@binding.bindable_dataclass
|
|
44
|
+
class Ipv4v6:
|
|
45
|
+
AddressData: Optional[list[IpAddress]] = field(default_factory=list) # used
|
|
46
|
+
#Addresses: Optional[list[list[int]]] = field(default_factory=list) # not used
|
|
47
|
+
#Dns: Optional[list[list[int]]] = field(default_factory=list) # not used
|
|
48
|
+
DnsData: Optional[list[DnsServer]] = field(default_factory=list) # used
|
|
49
|
+
DnsSearch: Optional[list[DnsServer]] = field(default_factory=list) # used
|
|
50
|
+
Gateway: Optional[str] = '' # used
|
|
51
|
+
IgnoreAutoDns: Optional[bool] = False # used
|
|
52
|
+
IgnoreAutoRoutes: Optional[bool] = False # used
|
|
53
|
+
Method: Optional[str] = '' # used
|
|
54
|
+
RouteData: Optional[list[IpRoute]] = field(default_factory=list) # used
|
|
55
|
+
#Routes: Optional[list[list[int]]] = field(default_factory=list) # not used
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@binding.bindable_dataclass
|
|
59
|
+
class Settings:
|
|
60
|
+
Connection: Optional[ConnectionDetails] = None
|
|
61
|
+
Ipv4: Optional[Ipv4v6] = None
|
|
62
|
+
Ipv6: Optional[Ipv4v6] = None
|
|
63
|
+
Proxy: Optional[str] = ''
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@binding.bindable_dataclass
|
|
67
|
+
class Device:
|
|
68
|
+
Proxy: Optional[ProxyInterface] = None
|
|
69
|
+
Path: Optional[str] = ''
|
|
70
|
+
ActiveConnectionPath: Optional[str] = ''
|
|
71
|
+
HardwareAddress: Optional[str] = ''
|
|
72
|
+
Flags: Optional[int] = None
|
|
73
|
+
Carrier: Optional[str] = ''
|
|
74
|
+
State: Optional[int] = True
|
|
75
|
+
DeviceState: Optional[str] = ''
|
|
76
|
+
Ip4ConfigPath : Optional[str] = ''
|
|
77
|
+
Ip6ConfigPath : Optional[str] = ''
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@binding.bindable_dataclass
|
|
81
|
+
class InterfaceData:
|
|
82
|
+
Name: Optional[str] = ''
|
|
83
|
+
HardwareAddress: Optional[str] = ''
|
|
84
|
+
StateString: Optional[str] = ''
|
|
85
|
+
StateNumber: Optional[int] = 0
|
|
86
|
+
Active: Optional[bool] = False
|
|
87
|
+
Status: Optional[str] = ''
|
|
88
|
+
Carrier: Optional[str] = ''
|
|
89
|
+
Ip4: Optional[str] = ''
|
|
90
|
+
Ip6: Optional[str] = ''
|
|
91
|
+
AutoConnect: Optional[bool] = False
|
|
92
|
+
_dev_path: Optional[str] = ''
|
|
93
|
+
_act_con_path: Optional[str] = ''
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
# ====================================================================
|
|
98
|
+
# Proxies
|
|
99
|
+
# ====================================================================
|
|
100
|
+
def GetNetworkManager(bus: MessageBus) -> ProxyInterface:
|
|
101
|
+
file_name = 'org.freedesktop.NetworkManager.xml'
|
|
102
|
+
with open(str(INTROSPECTION_DIR /file_name), "r") as f:
|
|
103
|
+
introspection = f.read()
|
|
104
|
+
obj = bus.get_proxy_object('org.freedesktop.NetworkManager', '/org/freedesktop/NetworkManager', introspection)
|
|
105
|
+
return obj.get_interface('org.freedesktop.NetworkManager')
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def GetDevice(bus: MessageBus, path :str) -> ProxyInterface:
|
|
109
|
+
file_name = 'org.freedesktop.NetworkManager.Device.xml'
|
|
110
|
+
with open(str(INTROSPECTION_DIR /file_name), "r") as f:
|
|
111
|
+
introspection = f.read()
|
|
112
|
+
obj = bus.get_proxy_object('org.freedesktop.NetworkManager', path, introspection)
|
|
113
|
+
return obj.get_interface('org.freedesktop.NetworkManager.Device')
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def GetActiveConnection(bus: MessageBus, path :str) -> ProxyInterface:
|
|
117
|
+
file_name = 'org.freedesktop.NetworkManager.Connection.Active.xml'
|
|
118
|
+
with open(str(INTROSPECTION_DIR /file_name), "r") as f:
|
|
119
|
+
introspection = f.read()
|
|
120
|
+
obj = bus.get_proxy_object('org.freedesktop.NetworkManager', path, introspection)
|
|
121
|
+
return obj.get_interface('org.freedesktop.NetworkManager.Connection.Active')
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def GetIp4Config(bus: MessageBus, path :str) -> ProxyInterface:
|
|
125
|
+
file_name = 'org.freedesktop.NetworkManager.IP4Config.xml'
|
|
126
|
+
with open(str(INTROSPECTION_DIR /file_name), "r") as f:
|
|
127
|
+
introspection = f.read()
|
|
128
|
+
obj = bus.get_proxy_object('org.freedesktop.NetworkManager', path, introspection)
|
|
129
|
+
return obj.get_interface('org.freedesktop.NetworkManager.IP4Config')
|
|
130
|
+
|
|
131
|
+
def GetIp6Config(bus: MessageBus, path :str) -> ProxyInterface:
|
|
132
|
+
file_name = 'org.freedesktop.NetworkManager.IP6Config.xml'
|
|
133
|
+
with open(str(INTROSPECTION_DIR /file_name), "r") as f:
|
|
134
|
+
introspection = f.read()
|
|
135
|
+
obj = bus.get_proxy_object('org.freedesktop.NetworkManager', path, introspection)
|
|
136
|
+
return obj.get_interface('org.freedesktop.NetworkManager.IP6Config')
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def GetSettingsManager(bus: MessageBus, path :str) -> ProxyInterface:
|
|
140
|
+
file_name = 'org.freedesktop.NetworkManager.Settings.xml'
|
|
141
|
+
with open(str(INTROSPECTION_DIR /file_name), "r") as f:
|
|
142
|
+
introspection = f.read()
|
|
143
|
+
obj = bus.get_proxy_object('org.freedesktop.NetworkManager', path, introspection)
|
|
144
|
+
return obj.get_interface('org.freedesktop.NetworkManager.Settings')
|
|
145
|
+
|
|
146
|
+
def GetConnection(bus: MessageBus, path : str)-> ProxyInterface:
|
|
147
|
+
file_name = 'org.freedesktop.NetworkManager.Settings.Connection.xml'
|
|
148
|
+
with open(str(INTROSPECTION_DIR /file_name), "r") as f:
|
|
149
|
+
introspection = f.read()
|
|
150
|
+
obj = bus.get_proxy_object('org.freedesktop.NetworkManager', path, introspection)
|
|
151
|
+
return obj.get_interface('org.freedesktop.NetworkManager.Settings.Connection')
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
async def GetConnectionFromDevice(bus: MessageBus, device :ProxyInterface) -> ProxyInterface:
|
|
155
|
+
active_connection_path = await device.get_active_connection()
|
|
156
|
+
if len(active_connection_path) > 1:
|
|
157
|
+
activeConnection = GetActiveConnection(bus, active_connection_path)
|
|
158
|
+
connection_path = await activeConnection.get_connection()
|
|
159
|
+
return GetConnection(bus, connection_path)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
# ====================================================================
|
|
163
|
+
# Getters and Setters
|
|
164
|
+
# ====================================================================
|
|
165
|
+
|
|
166
|
+
async def GetInterfaceData(bus: MessageBus, nm: ProxyInterface, iface :str) -> InterfaceData:
|
|
167
|
+
i = InterfaceData()
|
|
168
|
+
i._dev_path = await nm.call_get_device_by_ip_iface(iface)
|
|
169
|
+
dev = GetDevice(bus, i._dev_path)
|
|
170
|
+
i.Name = iface
|
|
171
|
+
i.HardwareAddress = await dev.get_hw_address()
|
|
172
|
+
i.StateNumber = await dev.get_state()
|
|
173
|
+
i.StateString = processDeviceState(i.StateNumber)
|
|
174
|
+
i.Active = True if i.StateNumber == 100 else False
|
|
175
|
+
i.Carrier = processInterfaceFlags(await dev.get_interface_flags())
|
|
176
|
+
|
|
177
|
+
ip4_config_path = await dev.get_ip4_config()
|
|
178
|
+
ip6_config_path = await dev.get_ip6_config()
|
|
179
|
+
|
|
180
|
+
i._act_con_path = await dev.get_active_connection()
|
|
181
|
+
|
|
182
|
+
if len(i._act_con_path) > 1:
|
|
183
|
+
activeConnection = GetActiveConnection(bus, i._act_con_path)
|
|
184
|
+
connection_path = await activeConnection.get_connection()
|
|
185
|
+
connection = GetConnection(bus, connection_path)
|
|
186
|
+
settings = await connection.call_get_settings()
|
|
187
|
+
i.AutoConnect = settings['connection'].get('autoconnect', Variant('b', True)).value
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
if len(ip4_config_path) > 1:
|
|
191
|
+
ip4Config = GetIp4Config(bus, ip4_config_path)
|
|
192
|
+
ip6Config = GetIp6Config(bus, ip6_config_path)
|
|
193
|
+
ip4AddressData = await ip4Config.get_address_data()
|
|
194
|
+
ip6AddressData = await ip6Config.get_address_data()
|
|
195
|
+
i.Ip4 = addressDataToString(ip4AddressData)
|
|
196
|
+
i.Ip6 = addressDataToString(ip6AddressData)
|
|
197
|
+
|
|
198
|
+
i.Status = combineAddresses(ip4AddressData, ip6AddressData)
|
|
199
|
+
|
|
200
|
+
return i
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
async def GetSettings(bus: MessageBus, dev: ProxyInterface) -> dict:
|
|
204
|
+
active_connection_path = await dev.get_active_connection()
|
|
205
|
+
if len(active_connection_path) > 1:
|
|
206
|
+
activeConnection = GetActiveConnection(bus, active_connection_path)
|
|
207
|
+
connection_path = await activeConnection.get_connection()
|
|
208
|
+
connection = GetConnection(bus, connection_path)
|
|
209
|
+
connection_settings = await connection.call_get_settings()
|
|
210
|
+
return connection_settings
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def GetIp(version: str, settings: dict) -> Ipv4v6:
|
|
217
|
+
|
|
218
|
+
ip = Ipv4v6()
|
|
219
|
+
|
|
220
|
+
ip_settings = settings.get(version)
|
|
221
|
+
|
|
222
|
+
ip_settings: dict
|
|
223
|
+
if ip_settings:
|
|
224
|
+
addrData = ip_settings.get('address-data')
|
|
225
|
+
if addrData:
|
|
226
|
+
for addr in addrData.value:
|
|
227
|
+
a = addr.get('address').value
|
|
228
|
+
p = addr.get('prefix').value
|
|
229
|
+
ip.AddressData.append(IpAddress(a, p))
|
|
230
|
+
|
|
231
|
+
dnsData = ip_settings.get('dns-data')
|
|
232
|
+
if dnsData:
|
|
233
|
+
for dns in dnsData.value:
|
|
234
|
+
ip.DnsData.append(DnsServer(dns))
|
|
235
|
+
|
|
236
|
+
dnsSearch = ip_settings.get('dns-search')
|
|
237
|
+
if dnsSearch:
|
|
238
|
+
for dns in dnsSearch.value:
|
|
239
|
+
ip.DnsSearch.append(DnsServer(dns))
|
|
240
|
+
|
|
241
|
+
gateway = ip_settings.get('gateway')
|
|
242
|
+
if gateway:
|
|
243
|
+
ip.Gateway = gateway.value
|
|
244
|
+
|
|
245
|
+
ignoreAutoDns = ip_settings.get('ignore-auto-dns')
|
|
246
|
+
if ignoreAutoDns:
|
|
247
|
+
ip.IgnoreAutoDns = ignoreAutoDns.value
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
ignoreAutoRoutes = ip_settings.get('ignore-auto-routes')
|
|
251
|
+
if ignoreAutoRoutes:
|
|
252
|
+
ip.IgnoreAutoRoutes = ignoreAutoRoutes.value
|
|
253
|
+
|
|
254
|
+
method = ip_settings.get('method')
|
|
255
|
+
if method:
|
|
256
|
+
ip.Method = method.value
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
routeData = ip_settings.get('route-data')
|
|
260
|
+
if routeData:
|
|
261
|
+
for route in routeData.value:
|
|
262
|
+
a = route.get('dest').value
|
|
263
|
+
p = route.get('prefix').value
|
|
264
|
+
n = route.get('next-hop').value
|
|
265
|
+
m = route.get('metric').value
|
|
266
|
+
ip.RouteData.append(IpRoute(a, p, n, m))
|
|
267
|
+
|
|
268
|
+
return ip
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
def SetIp(ip: Ipv4v6, version: str, settings :dict) -> dict:
|
|
273
|
+
|
|
274
|
+
#remove depreciated
|
|
275
|
+
settings[version].pop("addresses", None)
|
|
276
|
+
settings[version].pop("dns", None)
|
|
277
|
+
settings[version].pop("routes", None)
|
|
278
|
+
|
|
279
|
+
# address data
|
|
280
|
+
settings[version]['address-data'] = addresses_to_dbus(ip.AddressData)
|
|
281
|
+
# dns data
|
|
282
|
+
settings[version]['dns-data'] = dns_to_dbus(ip.DnsData)
|
|
283
|
+
# dns search
|
|
284
|
+
settings[version]['dns-search'] = dns_to_dbus(ip.DnsSearch)
|
|
285
|
+
# gateway
|
|
286
|
+
settings[version]['gateway'] = Variant('s', ip.Gateway)
|
|
287
|
+
# ignore auto dns
|
|
288
|
+
settings[version]['ignore-auto-dns'] = Variant('b', ( ip.IgnoreAutoDns))
|
|
289
|
+
# ignore auto routes
|
|
290
|
+
settings[version]['ignore-auto-routes'] = Variant('b', ( ip.IgnoreAutoRoutes))
|
|
291
|
+
# method
|
|
292
|
+
settings[version]['method'] = Variant('s', ip.Method)
|
|
293
|
+
#route data
|
|
294
|
+
settings[version]['route-data'] = route_to_dbus(ip.RouteData)
|
|
295
|
+
|
|
296
|
+
return settings
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
def addresses_to_dbus(ip :list[IpAddress]):
|
|
302
|
+
return Variant('aa{sv}', [{'address': Variant('s', i.Address), 'prefix': Variant('u', int(i.Prefix))} for i in ip])
|
|
303
|
+
|
|
304
|
+
def dns_to_dbus(dns :list[DnsServer]):
|
|
305
|
+
return Variant('as', [d.Server for d in dns])
|
|
306
|
+
|
|
307
|
+
def route_to_dbus(route: list[IpRoute]):
|
|
308
|
+
return Variant('aa{sv}', [{'dest': Variant('s', r.Dest),
|
|
309
|
+
'prefix': Variant('u', int(r.Prefix)),
|
|
310
|
+
'next-hop': Variant('s', r.NextHop),
|
|
311
|
+
'metric': Variant('u', int(r.Metric)),
|
|
312
|
+
} for r in route])
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
def ApplyModes(version :str, settings :dict) -> dict:
|
|
317
|
+
|
|
318
|
+
if settings[version]['method'].value == 'auto':
|
|
319
|
+
settings[version].pop('gateway', None)
|
|
320
|
+
|
|
321
|
+
if settings[version]['method'].value == 'disabled':
|
|
322
|
+
settings[version].pop('gateway', None)
|
|
323
|
+
|
|
324
|
+
return settings
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
def addressDataToAddress(addressdata: list[dict]) -> list:
|
|
331
|
+
formatted = []
|
|
332
|
+
for addr in addressdata:
|
|
333
|
+
address = addr.get('address')
|
|
334
|
+
prefix = addr.get('prefix')
|
|
335
|
+
if address and prefix:
|
|
336
|
+
formatted.append(f"{address.value}/{prefix.value}")
|
|
337
|
+
return formatted
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
def formatAddressString(addresses: list[str]) -> str:
|
|
341
|
+
return ', '.join(addresses) if addresses else ''
|
|
342
|
+
|
|
343
|
+
def formatInterfaceRow(interface :str, addresses: str):
|
|
344
|
+
return {"name": interface, "addresses": addresses}
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
def addressDataToString(addressData):
|
|
348
|
+
addresses = []
|
|
349
|
+
addresses.extend(addressDataToAddress(addressData))
|
|
350
|
+
if len(addresses) == 0:
|
|
351
|
+
return "disabled"
|
|
352
|
+
return formatAddressString(addresses)
|
|
353
|
+
|
|
354
|
+
def dnsDataToString(dnsData):
|
|
355
|
+
return formatAddressString(dnsData)
|
|
356
|
+
|
|
357
|
+
def processDeviceState(state: int) -> str:
|
|
358
|
+
state_dict = {0: ["UNKNOWN", "the device's state is unknown"],
|
|
359
|
+
10: ["UNMANAGED", "the device is recognized, but not managed by NetworkManager"],
|
|
360
|
+
20: ["UNAVAILABLE", "the device is managed by NetworkManager, but is not available for use. Reasons may include the wireless switched off, missing firmware, no ethernet carrier, missing supplicant or modem manager, etc."],
|
|
361
|
+
30: ["DISCONNECTED", "the device can be activated, but is currently idle and not connected to a network."],
|
|
362
|
+
40: ["PREPARE", "the device is preparing the connection to the network. This may include operations like changing the MAC address, setting physical link properties, and anything else required to connect to the requested network."],
|
|
363
|
+
50: ["CONFIG", "the device is connecting to the requested network. This may include operations like associating with the Wi-Fi AP, dialing the modem, connecting to the remote Bluetooth device, etc."],
|
|
364
|
+
60: ["NEED_AUTH", "the device requires more information to continue connecting to the requested network. This includes secrets like WiFi passphrases, login passwords, PIN codes, etc."],
|
|
365
|
+
70: ["IP_CONFIG", "the device is requesting IPv4 and/or IPv6 addresses and routing information from the network."],
|
|
366
|
+
80: ["IP_CHECK", "the device is checking whether further action is required for the requested network connection. This may include checking whether only local network access is available, whether a captive portal is blocking access to the Internet, etc."],
|
|
367
|
+
90: ["SECONDARIES", "the device is waiting for a secondary connection (like a VPN) which must activated before the device can be activated"],
|
|
368
|
+
100: ["ACTIVATED", "the device has a network connection, either local or global."],
|
|
369
|
+
110: ["DEACTIVATING", "a disconnection from the current network connection was requested, and the device is cleaning up resources used for that connection. The network connection may still be valid."],
|
|
370
|
+
120: ["FAILED", "the device failed to connect to the requested network and is cleaning up the connection request"]}
|
|
371
|
+
nmState = state_dict.get(state, "STATE NOT FOUND")
|
|
372
|
+
return nmState[0]
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
def processInterfaceFlags(flags: int) -> str:
|
|
376
|
+
NM_DEVICE_INTERFACE_FLAG_NONE= 0 # an alias for numeric zero, no flags set.
|
|
377
|
+
NM_DEVICE_INTERFACE_FLAG_UP= 0x1 # the interface is enabled from the administrative point of view. Corresponds to kernel IFF_UP.
|
|
378
|
+
NM_DEVICE_INTERFACE_FLAG_LOWER_UP= 0x2 # the physical link is up. Corresponds to kernel IFF_LOWER_UP.
|
|
379
|
+
NM_DEVICE_INTERFACE_FLAG_PROMISC= 0x4 # receive all packets. Corresponds to kernel IFF_PROMISC. Since: 1.32.
|
|
380
|
+
NM_DEVICE_INTERFACE_FLAG_CARRIER= 0x10000 # the interface has carrier. In most cases this is equal to the value of @NM_DEVICE_INTERFACE_FLAG_LOWER_UP. However some devices have a non-standard carrier detection mechanism.
|
|
381
|
+
NM_DEVICE_INTERFACE_FLAG_LLDP_CLIENT_ENABLED= 0x20000 # the flag to indicate device LLDP status. Since: 1.32.
|
|
382
|
+
"""Convert interface flags to detailed status string"""
|
|
383
|
+
|
|
384
|
+
if flags == 0:
|
|
385
|
+
return "Interface disabled (no flags set)"
|
|
386
|
+
|
|
387
|
+
status = []
|
|
388
|
+
|
|
389
|
+
if flags & NM_DEVICE_INTERFACE_FLAG_UP:
|
|
390
|
+
status.append("administratively up")
|
|
391
|
+
|
|
392
|
+
if flags & NM_DEVICE_INTERFACE_FLAG_LOWER_UP:
|
|
393
|
+
status.append("physical link up")
|
|
394
|
+
|
|
395
|
+
if flags & NM_DEVICE_INTERFACE_FLAG_CARRIER:
|
|
396
|
+
status.append("carrier detected")
|
|
397
|
+
|
|
398
|
+
if flags & NM_DEVICE_INTERFACE_FLAG_PROMISC:
|
|
399
|
+
status.append("promiscuous mode")
|
|
400
|
+
|
|
401
|
+
if flags & NM_DEVICE_INTERFACE_FLAG_LLDP_CLIENT_ENABLED:
|
|
402
|
+
status.append("LLDP enabled")
|
|
403
|
+
|
|
404
|
+
if not status:
|
|
405
|
+
return f"Unknown flags: 0x{flags:x}"
|
|
406
|
+
|
|
407
|
+
return " | ".join(status)
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
def combineAddresses(ipv4AddressData, ipv6AddressData) -> str:
|
|
411
|
+
|
|
412
|
+
addresses = []
|
|
413
|
+
addresses.extend(addressDataToAddress(ipv4AddressData))
|
|
414
|
+
addresses.extend(addressDataToAddress(ipv6AddressData))
|
|
415
|
+
return formatAddressString(addresses)
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
async def GetDeviceFromInterface(bus: MessageBus, iface :str) -> Device:
|
|
421
|
+
nm = GetNetworkManager(bus)
|
|
422
|
+
device_path = await nm.call_get_device_by_ip_iface(iface)
|
|
423
|
+
device = GetDevice(bus, device_path)
|
|
424
|
+
|
|
425
|
+
hwaddr = await device.get_hw_address()
|
|
426
|
+
flags = await device.get_interface_flags()
|
|
427
|
+
carrier = processInterfaceFlags(flags)
|
|
428
|
+
|
|
429
|
+
state = await device.get_state()
|
|
430
|
+
deviceState = processDeviceState(state)
|
|
431
|
+
ip4_config_path = await device.get_ip4_config()
|
|
432
|
+
ip4_config_path = await device.get_ip6_config()
|
|
433
|
+
active_connection_path = await device.get_active_connection()
|
|
434
|
+
|
|
435
|
+
myDevice = Device(
|
|
436
|
+
Proxy = device,
|
|
437
|
+
Path = device_path,
|
|
438
|
+
ActiveConnectionPath = active_connection_path,
|
|
439
|
+
HardwareAddress = hwaddr,
|
|
440
|
+
Flags = flags,
|
|
441
|
+
Carrier = carrier,
|
|
442
|
+
State = state,
|
|
443
|
+
DeviceState = deviceState,
|
|
444
|
+
Ip4ConfigPath = ip4_config_path,
|
|
445
|
+
Ip6ConfigPath = ip4_config_path)
|
|
446
|
+
|
|
447
|
+
return myDevice
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
def isAutoconnect(settings :dict) -> bool:
|
|
452
|
+
return settings['connection']
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
async def GetInterfaces(bus: MessageBus) -> list:
|
|
457
|
+
|
|
458
|
+
interfaces = []
|
|
459
|
+
|
|
460
|
+
nm = GetNetworkManager(bus)
|
|
461
|
+
|
|
462
|
+
devices_paths = await nm.call_get_devices()
|
|
463
|
+
|
|
464
|
+
for p in devices_paths:
|
|
465
|
+
dev = GetDevice(bus, p)
|
|
466
|
+
interfaces.append(await dev.get_interface())
|
|
467
|
+
|
|
468
|
+
return interfaces
|
|
469
|
+
|
|
470
|
+
async def GetInterfacesAndAddresses(bus: MessageBus) -> list:
|
|
471
|
+
|
|
472
|
+
rows = []
|
|
473
|
+
|
|
474
|
+
nm = GetNetworkManager(bus)
|
|
475
|
+
|
|
476
|
+
device_paths = await nm.call_get_devices()
|
|
477
|
+
|
|
478
|
+
for devicePath in device_paths:
|
|
479
|
+
|
|
480
|
+
device = GetDevice(bus, devicePath)
|
|
481
|
+
interface = await device.get_interface()
|
|
482
|
+
hwaddr = await device.get_hw_address()
|
|
483
|
+
state = await device.get_state()
|
|
484
|
+
processDeviceState
|
|
485
|
+
ip4_config_path = await device.get_ip4_config()
|
|
486
|
+
ip6_config_path = await device.get_ip6_config()
|
|
487
|
+
if len(ip4_config_path) > 1:
|
|
488
|
+
|
|
489
|
+
ip4Config = GetIp4Config(bus, ip4_config_path)
|
|
490
|
+
ip6Config = GetIp6Config(bus, ip6_config_path)
|
|
491
|
+
|
|
492
|
+
ip4AddressData = await ip4Config.get_address_data()
|
|
493
|
+
ip6AddressData = await ip6Config.get_address_data()
|
|
494
|
+
|
|
495
|
+
gw = []
|
|
496
|
+
ip4gw = await ip4Config.get_gateway()
|
|
497
|
+
if ip4gw:
|
|
498
|
+
gw.append(ip4gw)
|
|
499
|
+
ip6gw = await ip6Config.get_gateway()
|
|
500
|
+
if ip6gw:
|
|
501
|
+
gw.append(ip4gw)
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
rows.append({'name': interface,
|
|
506
|
+
'addresses': combineAddresses(ip4AddressData, ip6AddressData),
|
|
507
|
+
'state':processDeviceState(state),
|
|
508
|
+
'gateway': formatListToString(gw),
|
|
509
|
+
'hw address': hwaddr})
|
|
510
|
+
|
|
511
|
+
return rows
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
async def nm_call(bus: MessageBus, member: str, signature:str, body):
|
|
515
|
+
|
|
516
|
+
rsp = await bus.call(
|
|
517
|
+
Message(
|
|
518
|
+
destination='org.freedesktop.NetworkManager',
|
|
519
|
+
path='/org/freedesktop/NetworkManager',
|
|
520
|
+
interface='org.freedesktop.NetworkManager',
|
|
521
|
+
member=member,
|
|
522
|
+
signature=signature,
|
|
523
|
+
body=[body]
|
|
524
|
+
)
|
|
525
|
+
)
|
|
526
|
+
|
|
527
|
+
if rsp.body:
|
|
528
|
+
return rsp.body[0]
|