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