netlink_packet_route/rtnl/neighbour/
message.rs1use anyhow::Context;
4
5use crate::{
6 nlas::neighbour::Nla,
7 traits::{Emitable, Parseable},
8 DecodeError,
9 NeighbourHeader,
10 NeighbourMessageBuffer,
11};
12
13#[derive(Debug, PartialEq, Eq, Clone, Default)]
14pub struct NeighbourMessage {
15 pub header: NeighbourHeader,
16 pub nlas: Vec<Nla>,
17}
18
19impl Emitable for NeighbourMessage {
20 fn buffer_len(&self) -> usize {
21 self.header.buffer_len() + self.nlas.as_slice().buffer_len()
22 }
23
24 fn emit(&self, buffer: &mut [u8]) {
25 self.header.emit(buffer);
26 self.nlas
27 .as_slice()
28 .emit(&mut buffer[self.header.buffer_len()..]);
29 }
30}
31
32impl<'a, T: AsRef<[u8]> + 'a> Parseable<NeighbourMessageBuffer<&'a T>> for NeighbourMessage {
33 fn parse(buf: &NeighbourMessageBuffer<&'a T>) -> Result<Self, DecodeError> {
34 Ok(NeighbourMessage {
35 header: NeighbourHeader::parse(buf)
36 .context("failed to parse neighbour message header")?,
37 nlas: Vec::<Nla>::parse(buf).context("failed to parse neighbour message NLAs")?,
38 })
39 }
40}
41
42impl<'a, T: AsRef<[u8]> + 'a> Parseable<NeighbourMessageBuffer<&'a T>> for Vec<Nla> {
43 fn parse(buf: &NeighbourMessageBuffer<&'a T>) -> Result<Self, DecodeError> {
44 let mut nlas = vec![];
45 for nla_buf in buf.nlas() {
46 nlas.push(Nla::parse(&nla_buf?)?);
47 }
48 Ok(nlas)
49 }
50}
51
52#[cfg(test)]
53mod test {
54 use crate::{
55 constants::*,
56 traits::Emitable,
57 NeighbourHeader,
58 NeighbourMessage,
59 NeighbourMessageBuffer,
60 };
61
62 #[rustfmt::skip]
69 static HEADER: [u8; 12] = [
70 0x0a, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x80, 0x01 ];
80
81 #[test]
82 fn packet_header_read() {
83 let packet = NeighbourMessageBuffer::new(&HEADER[0..12]);
84 assert_eq!(packet.family(), AF_INET6 as u8);
85 assert_eq!(packet.ifindex(), 1);
86 assert_eq!(packet.state(), NUD_REACHABLE);
87 assert_eq!(packet.flags(), NTF_ROUTER);
88 assert_eq!(packet.ntype(), NDA_DST as u8);
89 }
90
91 #[test]
92 fn packet_header_build() {
93 let mut buf = vec![0xff; 12];
94 {
95 let mut packet = NeighbourMessageBuffer::new(&mut buf);
96 packet.set_family(AF_INET6 as u8);
97 packet.set_ifindex(1);
98 packet.set_state(NUD_REACHABLE);
99 packet.set_flags(NTF_ROUTER);
100 packet.set_ntype(NDA_DST as u8);
101 }
102 assert_eq!(&buf[..], &HEADER[0..12]);
103 }
104
105 #[test]
106 fn emit() {
107 let header = NeighbourHeader {
108 family: AF_INET6 as u8,
109 ifindex: 1,
110 state: NUD_REACHABLE,
111 flags: NTF_ROUTER,
112 ntype: NDA_DST as u8,
113 };
114
115 let nlas = vec![];
116 let packet = NeighbourMessage { header, nlas };
117 let mut buf = vec![0; 12];
118
119 assert_eq!(packet.buffer_len(), 12);
120 packet.emit(&mut buf[..]);
121 }
122}