netlink_packet_netfilter/none/
message.rs1use netlink_packet_core::{
4 DecodeError, DefaultNla, Emitable, ErrorContext as _, ParseableParametrized,
5};
6
7use crate::nlas::default_nlas;
8
9#[derive(Debug, PartialEq, Eq, Clone)]
10#[non_exhaustive]
11pub enum ControlMessage {
12 BatchBegin,
13 BatchEnd,
14 Other {
15 message_type: u8,
16 attributes: Vec<DefaultNla>,
17 },
18}
19
20const NFNL_MSG_BATCH_BEGIN: u8 = 16;
22const NFNL_MSG_BATCH_END: u8 = 17;
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
25#[non_exhaustive]
26pub enum ControlMessageType {
27 BatchBegin,
28 BatchEnd,
29 Other(u8),
30}
31
32impl From<u8> for ControlMessageType {
33 fn from(value: u8) -> Self {
34 match value {
35 NFNL_MSG_BATCH_BEGIN => Self::BatchBegin,
36 NFNL_MSG_BATCH_END => Self::BatchEnd,
37 v => Self::Other(v),
38 }
39 }
40}
41
42impl From<ControlMessageType> for u8 {
43 fn from(value: ControlMessageType) -> Self {
44 match value {
45 ControlMessageType::BatchBegin => NFNL_MSG_BATCH_BEGIN,
46 ControlMessageType::BatchEnd => NFNL_MSG_BATCH_END,
47 ControlMessageType::Other(v) => v,
48 }
49 }
50}
51
52impl ControlMessage {
53 pub fn message_type(&self) -> ControlMessageType {
54 match self {
55 Self::BatchBegin => ControlMessageType::BatchBegin,
56 Self::BatchEnd => ControlMessageType::BatchEnd,
57 Self::Other { message_type, .. } => (*message_type).into(),
58 }
59 }
60}
61
62impl Emitable for ControlMessage {
63 fn buffer_len(&self) -> usize {
64 match self {
65 Self::BatchBegin | Self::BatchEnd => 0,
66 Self::Other { attributes, .. } => {
67 attributes.as_slice().buffer_len()
68 }
69 }
70 }
71
72 fn emit(&self, buffer: &mut [u8]) {
73 match self {
74 Self::BatchBegin | Self::BatchEnd => {}
75 Self::Other { attributes, .. } => {
76 attributes.as_slice().emit(buffer)
77 }
78 }
79 }
80}
81
82impl ParseableParametrized<[u8], u8> for ControlMessage {
83 fn parse_with_param(
84 buf: &[u8],
85 message_type: u8,
86 ) -> Result<Self, DecodeError> {
87 Ok(match ControlMessageType::from(message_type) {
88 ControlMessageType::BatchBegin => Self::BatchBegin,
89 ControlMessageType::BatchEnd => Self::BatchEnd,
90 ControlMessageType::Other(_) => {
91 let attributes =
92 default_nlas(buf).context("failed to parse message nla")?;
93 Self::Other {
94 message_type,
95 attributes,
96 }
97 }
98 })
99 }
100}