netlink_packet_core/
header.rs1use crate::{
4 buffer::NETLINK_HEADER_LEN, DecodeError, Emitable, NetlinkBuffer, Parseable,
5};
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<T: AsRef<[u8]> + ?Sized> Parseable<NetlinkBuffer<&T>> for NetlinkHeader {
58 fn parse(buf: &NetlinkBuffer<&T>) -> Result<NetlinkHeader, DecodeError> {
59 Ok(NetlinkHeader {
60 length: buf.length(),
61 message_type: buf.message_type(),
62 flags: buf.flags(),
63 sequence_number: buf.sequence_number(),
64 port_number: buf.port_number(),
65 })
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72 use crate::constants::*;
73
74 #[rustfmt::skip]
76 static IP_LINK_SHOW_PKT: [u8; 40] = [
77 0x28, 0x00, 0x00, 0x00, 0x12, 0x00, 0x01, 0x03, 0x34, 0x0e, 0xf9, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x08, 0x00, 0x1d, 0x00, 0x01, 0x00, 0x00, 0x00];
86
87 const RTM_GETLINK: u16 = 18;
88
89 #[test]
90 fn repr_parse() {
91 let repr = NetlinkHeader::parse(
92 &NetlinkBuffer::new_checked(&IP_LINK_SHOW_PKT[..]).unwrap(),
93 )
94 .unwrap();
95 assert_eq!(repr.length, 40);
96 assert_eq!(repr.message_type, RTM_GETLINK);
97 assert_eq!(repr.sequence_number, 1_526_271_540);
98 assert_eq!(repr.port_number, 0);
99 assert_eq!(repr.flags, NLM_F_ROOT | NLM_F_REQUEST | NLM_F_MATCH);
100 }
101
102 #[test]
103 fn repr_emit() {
104 let repr = NetlinkHeader {
105 length: 40,
106 message_type: RTM_GETLINK,
107 sequence_number: 1_526_271_540,
108 flags: NLM_F_ROOT | NLM_F_REQUEST | NLM_F_MATCH,
109 port_number: 0,
110 };
111 assert_eq!(repr.buffer_len(), 16);
112 let mut buf = [0; 16];
113 repr.emit(&mut buf[..]);
114 assert_eq!(&buf[..], &IP_LINK_SHOW_PKT[..16]);
115 }
116}