netlink_packet_route/rtnl/nsid/
message.rs1use anyhow::Context;
4
5use crate::{
6 nlas::nsid::Nla,
7 traits::{Emitable, Parseable},
8 DecodeError,
9 NsidHeader,
10 NsidMessageBuffer,
11};
12
13#[derive(Debug, PartialEq, Eq, Clone, Default)]
14pub struct NsidMessage {
15 pub header: NsidHeader,
16 pub nlas: Vec<Nla>,
17}
18
19impl<'a, T: AsRef<[u8]> + 'a> Parseable<NsidMessageBuffer<&'a T>> for NsidMessage {
20 fn parse(buf: &NsidMessageBuffer<&'a T>) -> Result<Self, DecodeError> {
21 Ok(Self {
22 header: NsidHeader::parse(buf).context("failed to parse nsid message header")?,
23 nlas: Vec::<Nla>::parse(buf).context("failed to parse nsid message NLAs")?,
24 })
25 }
26}
27
28impl<'a, T: AsRef<[u8]> + 'a> Parseable<NsidMessageBuffer<&'a T>> for Vec<Nla> {
29 fn parse(buf: &NsidMessageBuffer<&'a T>) -> Result<Self, DecodeError> {
30 let mut nlas = vec![];
31 for nla_buf in buf.nlas() {
32 nlas.push(Nla::parse(&nla_buf?)?);
33 }
34 Ok(nlas)
35 }
36}
37
38impl Emitable for NsidMessage {
39 fn buffer_len(&self) -> usize {
40 self.header.buffer_len() + self.nlas.as_slice().buffer_len()
41 }
42
43 fn emit(&self, buffer: &mut [u8]) {
44 self.header.emit(buffer);
45 self.nlas
46 .as_slice()
47 .emit(&mut buffer[self.header.buffer_len()..]);
48 }
49}
50
51#[cfg(test)]
52mod test {
53 use crate::{
54 nlas::nsid::Nla,
55 traits::ParseableParametrized,
56 NetlinkBuffer,
57 NsidHeader,
58 NsidMessage,
59 RtnlMessage,
60 RtnlMessageBuffer,
61 NETNSA_NSID_NOT_ASSIGNED,
62 RTM_GETNSID,
63 RTM_NEWNSID,
64 };
65
66 #[rustfmt::skip]
67 #[test]
68 fn get_ns_id_request() {
69 let data = vec![
70 0x1c, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00 ];
84 let expected = RtnlMessage::GetNsId(NsidMessage {
85 header: NsidHeader { rtgen_family: 0 },
86 nlas: vec![Nla::Fd(4)],
87 });
88 let actual = RtnlMessage::parse_with_param(&RtnlMessageBuffer::new(&NetlinkBuffer::new(&data).payload()), RTM_GETNSID).unwrap();
89 assert_eq!(expected, actual);
90 }
91
92 #[rustfmt::skip]
93 #[test]
94 fn get_ns_id_response() {
95 let data = vec![
96 0x1c, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff ];
110 let expected = RtnlMessage::NewNsId(NsidMessage {
111 header: NsidHeader { rtgen_family: 0 },
112 nlas: vec![Nla::Id(NETNSA_NSID_NOT_ASSIGNED)],
113 });
114 let nl_buffer = NetlinkBuffer::new(&data).payload();
115 let rtnl_buffer = RtnlMessageBuffer::new(&nl_buffer);
116 let actual = RtnlMessage::parse_with_param(&rtnl_buffer, RTM_NEWNSID).unwrap();
117 assert_eq!(expected, actual);
118 }
119}