linux_info/network/
network_manager.rs1use std::time::Duration;
4use std::sync::Arc;
5use std::net::Ipv4Addr;
6
7use dbus::{Error, Path};
8use dbus::blocking::{Connection, Proxy};
9use dbus::arg::RefArg;
10
11use nmdbus::NetworkManager as DbusNetworkManager;
12use nmdbus::device::Device as DeviceTrait;
13use nmdbus::device_modem::DeviceModem;
14use nmdbus::ip4config::IP4Config;
15
16const DBUS_NAME: &str = "org.freedesktop.NetworkManager";
17const DBUS_PATH: &str = "/org/freedesktop/NetworkManager";
18const TIMEOUT: Duration = Duration::from_secs(2);
19
20#[derive(Clone)]
21struct Dbus {
22 conn: Arc<Connection>
23}
24
25impl Dbus {
26 fn connect() -> Result<Self, Error> {
27 Connection::new_system()
28 .map(Arc::new)
29 .map(|conn| Self { conn })
30 }
31
32 fn proxy<'a, 'b>(
33 &'b self,
34 path: impl Into<Path<'a>>
35 ) -> Proxy<'a, &'b Connection> {
36 self.conn.with_proxy(DBUS_NAME, path, TIMEOUT)
37 }
38}
39
40#[derive(Clone)]
41pub struct NetworkManager {
42 dbus: Dbus
43}
44
45impl NetworkManager {
46 pub fn connect() -> Result<Self, Error> {
47 Dbus::connect()
48 .map(|dbus| Self { dbus })
49 }
50
51 pub fn devices(&self) -> Result<Vec<Device>, Error> {
52 let paths = self.dbus.proxy(DBUS_PATH).get_devices()?;
53 let devices = paths.into_iter()
54 .map(|path| {
55 Device {
56 dbus: self.dbus.clone(),
57 path
58 }
59 })
60 .collect();
61
62 Ok(devices)
63 }
64}
65
66pub struct Device {
67 dbus: Dbus,
68 path: Path<'static>
69}
70
71impl Device {
72 pub fn path(&self) -> Result<String, Error> {
76 self.dbus.proxy(&self.path).path()
77 }
78
79 pub fn interface(&self) -> Result<String, Error> {
84 self.dbus.proxy(&self.path).interface()
85 }
86
87 pub fn driver(&self) -> Result<String, Error> {
90 self.dbus.proxy(&self.path).driver()
91 }
92
93 pub fn state(&self) -> Result<DeviceState, Error> {
95 DeviceTrait::state(&self.dbus.proxy(&self.path))
96 .map(Into::into)
97 }
98
99 pub fn kind(&self) -> Result<DeviceKind, Error> {
101 self.dbus.proxy(&self.path).device_type()
102 .map(Into::into)
103 }
104
105 pub fn ipv4_config(&self) -> Result<Ipv4Config, Error> {
108 self.dbus.proxy(&self.path).ip4_config()
109 .map(|path| Ipv4Config {
110 dbus: self.dbus.clone(),
111 path
112 })
113 }
114
115 pub fn modem_apn(&self) -> Result<String, Error> {
117 self.dbus.proxy(&self.path).apn()
118 }
119}
120
121pub struct Ipv4Config {
122 dbus: Dbus,
123 path: Path<'static>
124}
125
126impl Ipv4Config {
127 pub fn addresses(&self) -> Result<Vec<Ipv4Addr>, Error> {
128 let data = self.dbus.proxy(&self.path).address_data()?;
129 let addrs = data.into_iter()
130 .filter_map(|mut d| d.remove("address"))
131 .filter_map(|addr| {
132 addr.as_str()?
133 .parse().ok()
134 })
135 .collect();
136
137 Ok(addrs)
138 }
139}
140
141#[repr(u32)]
142#[derive(Debug, Clone, Copy, PartialEq, Eq)]
143#[cfg_attr(
144 feature = "serde",
145 derive(serde1::Serialize, serde1::Deserialize),
146 serde(crate = "serde1")
147)]
148pub enum DeviceKind {
149 Unknown = 0,
151 Generic = 14,
153 Ethernet = 1,
155 Wifi = 2,
157 Unused1 = 3,
159 Unused2 = 4,
161 Bt = 5,
163 OlpcMesh = 6,
165 Wimax = 7,
167 Modem = 8,
170 Infiniband = 9,
172 Bond = 10,
174 Vlan = 11,
176 Adsl = 12,
178 Bridge = 13,
180 Team = 15,
182 Tun = 16,
184 IpTunnel = 17,
186 Macvlan = 18,
188 Vxlan = 19,
190 Veth = 20,
192 Macsec = 21,
194 Dummy = 22,
196 Ppp = 23,
198 OvsInterface = 24,
200 OvsPort = 25,
202 OvsBridge = 26,
204 Wpan = 27,
206 SixLowPan = 28,
208 Wireguard = 29,
210 WifiP2p = 30,
212 Vrf = 31
214}
215
216impl From<u32> for DeviceKind {
217 fn from(num: u32) -> Self {
218 if num > 31 {
219 Self::Unknown
220 } else {
221 unsafe {
222 *(&num as *const u32 as *const Self)
223 }
224 }
225 }
226}
227
228#[repr(u32)]
229#[derive(Debug, Clone, Copy, PartialEq, Eq)]
230#[cfg_attr(
231 feature = "serde",
232 derive(serde1::Serialize, serde1::Deserialize),
233 serde(crate = "serde1")
234)]
235pub enum DeviceState {
236 Unknown = 0,
238 Unmanaged = 10,
240 Unavailable = 20,
244 Disconnected = 30,
247 Prepare = 40,
252 Config = 50,
256 NeedAuth = 60,
260 IpConfig = 70,
263 IpCheck = 80,
268 Secondaries = 90,
271 Activated = 100,
273 Deactivating = 110,
277 Failed = 120
280}
281
282impl From<u32> for DeviceState {
283 fn from(num: u32) -> Self {
284 if num > 120 || num % 10 != 0 {
285 Self::Unknown
286 } else {
287 unsafe {
288 *(&num as *const u32 as *const Self)
289 }
290 }
291 }
292}