netlink_packet_wireguard/
message.rs1use netlink_packet_core::{
4 DecodeError, Emitable, ErrorContext, NlasIterator, Parseable,
5 ParseableParametrized,
6};
7use netlink_packet_generic::{GenlFamily, GenlHeader};
8
9use crate::WireguardAttribute;
10
11const WG_CMD_GET_DEVICE: u8 = 0;
12const WG_CMD_SET_DEVICE: u8 = 1;
13
14#[derive(Clone, Copy, Debug, PartialEq, Eq)]
15#[non_exhaustive]
16pub enum WireguardCmd {
17 GetDevice,
18 SetDevice,
19 Other(u8),
20}
21
22impl From<WireguardCmd> for u8 {
23 fn from(cmd: WireguardCmd) -> Self {
24 match cmd {
25 WireguardCmd::GetDevice => WG_CMD_GET_DEVICE,
26 WireguardCmd::SetDevice => WG_CMD_SET_DEVICE,
27 WireguardCmd::Other(d) => d,
28 }
29 }
30}
31
32impl From<u8> for WireguardCmd {
33 fn from(value: u8) -> Self {
34 match value {
35 WG_CMD_GET_DEVICE => Self::GetDevice,
36 WG_CMD_SET_DEVICE => Self::SetDevice,
37 cmd => Self::Other(cmd),
38 }
39 }
40}
41
42#[derive(Clone, Debug, PartialEq, Eq)]
43pub struct WireguardMessage {
44 pub cmd: WireguardCmd,
45 pub attributes: Vec<WireguardAttribute>,
46}
47
48impl GenlFamily for WireguardMessage {
49 fn family_name() -> &'static str {
50 "wireguard"
51 }
52
53 fn version(&self) -> u8 {
54 1
55 }
56
57 fn command(&self) -> u8 {
58 self.cmd.into()
59 }
60}
61
62impl Emitable for WireguardMessage {
63 fn emit(&self, buffer: &mut [u8]) {
64 self.attributes.as_slice().emit(buffer)
65 }
66
67 fn buffer_len(&self) -> usize {
68 self.attributes.as_slice().buffer_len()
69 }
70}
71
72impl ParseableParametrized<[u8], GenlHeader> for WireguardMessage {
73 fn parse_with_param(
74 buf: &[u8],
75 header: GenlHeader,
76 ) -> Result<Self, DecodeError> {
77 Ok(Self {
78 cmd: header.cmd.into(),
79 attributes: parse_attributes(buf)?,
80 })
81 }
82}
83
84fn parse_attributes(
85 buf: &[u8],
86) -> Result<Vec<WireguardAttribute>, DecodeError> {
87 let mut attributes = Vec::new();
88 let error_msg = "failed to parse wireguard netlink attributes";
89 for nla in NlasIterator::new(buf) {
90 let nla = &nla.context(error_msg)?;
91 let parsed = WireguardAttribute::parse(nla)?;
92 attributes.push(parsed);
93 }
94 Ok(attributes)
95}