netlink_packet_core/
header.rs
1use netlink_packet_utils::DecodeError;
4
5use crate::buffer::NETLINK_HEADER_LEN;
6use crate::{Emitable, NetlinkBuffer, Parseable};
7
8#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Default)]
24#[non_exhaustive]
25pub struct NetlinkHeader {
26 pub length: u32,
28
29 pub message_type: u16,
32
33 pub flags: u16,
35
36 pub sequence_number: u32,
38
39 pub port_number: u32,
41}
42
43impl Emitable for NetlinkHeader {
44 fn buffer_len(&self) -> usize {
45 NETLINK_HEADER_LEN
46 }
47
48 fn emit(&self, buffer: &mut [u8]) {
49 let mut buffer = NetlinkBuffer::new(buffer);
50 buffer.set_message_type(self.message_type);
51 buffer.set_length(self.length);
52 buffer.set_flags(self.flags);
53 buffer.set_sequence_number(self.sequence_number);
54 buffer.set_port_number(self.port_number);
55 }
56}
57
58impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NetlinkBuffer<&'a T>> for NetlinkHeader {
59 type Error = DecodeError;
60 fn parse(buf: &NetlinkBuffer<&'a T>) -> Result<NetlinkHeader, DecodeError> {
61 Ok(NetlinkHeader {
62 length: buf.length(),
63 message_type: buf.message_type(),
64 flags: buf.flags(),
65 sequence_number: buf.sequence_number(),
66 port_number: buf.port_number(),
67 })
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74 use crate::constants::*;
75
76 #[rustfmt::skip]
78 static IP_LINK_SHOW_PKT: [u8; 40] = [
79 0x28, 0x00, 0x00, 0x00, 0x12, 0x00, 0x01, 0x03, 0x34, 0x0e, 0xf9, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87 0x08, 0x00, 0x1d, 0x00, 0x01, 0x00, 0x00, 0x00];
88
89 const RTM_GETLINK: u16 = 18;
90
91 #[test]
92 fn repr_parse() {
93 let repr =
94 NetlinkHeader::parse(&NetlinkBuffer::new_checked(&IP_LINK_SHOW_PKT[..]).unwrap())
95 .unwrap();
96 assert_eq!(repr.length, 40);
97 assert_eq!(repr.message_type, RTM_GETLINK);
98 assert_eq!(repr.sequence_number, 1_526_271_540);
99 assert_eq!(repr.port_number, 0);
100 assert_eq!(repr.flags, NLM_F_ROOT | NLM_F_REQUEST | NLM_F_MATCH);
101 }
102
103 #[test]
104 fn repr_emit() {
105 let repr = NetlinkHeader {
106 length: 40,
107 message_type: RTM_GETLINK,
108 sequence_number: 1_526_271_540,
109 flags: NLM_F_ROOT | NLM_F_REQUEST | NLM_F_MATCH,
110 port_number: 0,
111 };
112 assert_eq!(repr.buffer_len(), 16);
113 let mut buf = vec![0; 16];
114 repr.emit(&mut buf[..]);
115 assert_eq!(&buf[..], &IP_LINK_SHOW_PKT[..16]);
116 }
117}