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