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