netlink_packet_core/
header.rs1use netlink_packet_utils::DecodeError;
4
5use crate::{buffer::NETLINK_HEADER_LEN, Emitable, NetlinkBuffer, Parseable};
6
7#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Default)]
23#[non_exhaustive]
24pub struct NetlinkHeader {
25 pub length: u32,
27
28 pub message_type: u16,
31
32 pub flags: u16,
34
35 pub sequence_number: u32,
37
38 pub port_number: u32,
40}
41
42impl Emitable for NetlinkHeader {
43 fn buffer_len(&self) -> usize {
44 NETLINK_HEADER_LEN
45 }
46
47 fn emit(&self, buffer: &mut [u8]) {
48 let mut buffer = NetlinkBuffer::new(buffer);
49 buffer.set_message_type(self.message_type);
50 buffer.set_length(self.length);
51 buffer.set_flags(self.flags);
52 buffer.set_sequence_number(self.sequence_number);
53 buffer.set_port_number(self.port_number);
54 }
55}
56
57impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NetlinkBuffer<&'a T>>
58 for NetlinkHeader
59{
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 = NetlinkHeader::parse(
94 &NetlinkBuffer::new_checked(&IP_LINK_SHOW_PKT[..]).unwrap(),
95 )
96 .unwrap();
97 assert_eq!(repr.length, 40);
98 assert_eq!(repr.message_type, RTM_GETLINK);
99 assert_eq!(repr.sequence_number, 1_526_271_540);
100 assert_eq!(repr.port_number, 0);
101 assert_eq!(repr.flags, NLM_F_ROOT | NLM_F_REQUEST | NLM_F_MATCH);
102 }
103
104 #[test]
105 fn repr_emit() {
106 let repr = NetlinkHeader {
107 length: 40,
108 message_type: RTM_GETLINK,
109 sequence_number: 1_526_271_540,
110 flags: NLM_F_ROOT | NLM_F_REQUEST | NLM_F_MATCH,
111 port_number: 0,
112 };
113 assert_eq!(repr.buffer_len(), 16);
114 let mut buf = vec![0; 16];
115 repr.emit(&mut buf[..]);
116 assert_eq!(&buf[..], &IP_LINK_SHOW_PKT[..16]);
117 }
118}