1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
use super::list_device_names_utils;
use super::{link_message, WireGuardDeviceLinkOperation};
use crate::err::{ConnectError, LinkDeviceError, ListDevicesError};
use list_device_names_utils::PotentialWireGuardDeviceName;
use neli::consts::{Ifla, NlFamily, Nlmsg};
use neli::rtnl::Ifinfomsg;
use neli::socket::NlSocket;
pub struct RouteSocket {
sock: NlSocket,
}
impl RouteSocket {
pub fn connect() -> Result<Self, ConnectError> {
let track_seq = true;
let mut sock = NlSocket::new(NlFamily::Route, track_seq)?;
let pid = None;
let groups = None;
sock.bind(pid, groups)?;
Ok(Self { sock })
}
pub fn add_device(&mut self, ifname: &str) -> Result<(), LinkDeviceError> {
let operation = WireGuardDeviceLinkOperation::Add;
self.sock.send_nl(link_message(ifname, operation)?)?;
self.sock.recv_ack()?;
Ok(())
}
pub fn del_device(&mut self, ifname: &str) -> Result<(), LinkDeviceError> {
let operation = WireGuardDeviceLinkOperation::Delete;
self.sock.send_nl(link_message(ifname, operation)?)?;
self.sock.recv_ack()?;
Ok(())
}
pub fn list_device_names(&mut self) -> Result<Vec<String>, ListDevicesError> {
self.sock
.send_nl(list_device_names_utils::get_list_device_names_msg())?;
let mut iter = self.sock.iter::<Nlmsg, Ifinfomsg<Ifla>>();
let mut result_names = vec![];
while let Some(Ok(response)) = iter.next() {
match response.nl_type {
Nlmsg::Error => return Err(ListDevicesError::Unknown),
Nlmsg::Done => break,
_ => (),
};
let PotentialWireGuardDeviceName {
is_wireguard,
ifname,
} = list_device_names_utils::parse_ifinfomsg(response)?;
if is_wireguard {
if let Some(ifname) = ifname {
result_names.push(ifname);
}
}
}
Ok(result_names)
}
}