reyzell_netlink_packet_netfilter/
message.rs

1// SPDX-License-Identifier: MIT
2
3use netlink_packet_core::{
4    NetlinkDeserializable, NetlinkHeader, NetlinkPayload, NetlinkSerializable,
5};
6use netlink_packet_utils::{
7    buffer, nla::DefaultNla, DecodeError, Emitable, Parseable,
8    ParseableParametrized,
9};
10
11use crate::{
12    buffer::NetfilterBuffer, nfconntrack::NfConntrackMessage,
13    nflog::NfLogMessage,
14};
15
16pub const NETFILTER_HEADER_LEN: usize = 4;
17
18buffer!(NetfilterHeaderBuffer(NETFILTER_HEADER_LEN) {
19    family: (u8, 0),
20    version: (u8, 1),
21    res_id: (u16, 2..4),
22});
23
24#[derive(Clone, Debug, PartialEq, Eq)]
25pub struct NetfilterHeader {
26    pub family: u8,
27    pub version: u8,
28    pub res_id: u16,
29}
30
31impl NetfilterHeader {
32    pub fn new(family: u8, version: u8, res_id: u16) -> Self {
33        Self {
34            family,
35            version,
36            res_id,
37        }
38    }
39}
40
41impl Emitable for NetfilterHeader {
42    fn buffer_len(&self) -> usize {
43        NETFILTER_HEADER_LEN
44    }
45
46    fn emit(&self, buf: &mut [u8]) {
47        let mut buf = NetfilterHeaderBuffer::new(buf);
48        buf.set_family(self.family);
49        buf.set_version(self.version);
50        buf.set_res_id(self.res_id.to_be());
51    }
52}
53
54impl<T: AsRef<[u8]>> Parseable<NetfilterHeaderBuffer<T>> for NetfilterHeader {
55    fn parse(buf: &NetfilterHeaderBuffer<T>) -> Result<Self, DecodeError> {
56        buf.check_buffer_length()?;
57        Ok(NetfilterHeader {
58            family: buf.family(),
59            version: buf.version(),
60            res_id: u16::from_be(buf.res_id()),
61        })
62    }
63}
64
65#[derive(Debug, PartialEq, Eq, Clone)]
66pub enum NetfilterMessageInner {
67    NfConntrack(NfConntrackMessage),
68    NfLog(NfLogMessage),
69    Other {
70        subsys: u8,
71        message_type: u8,
72        nlas: Vec<DefaultNla>,
73    },
74}
75
76impl From<NfConntrackMessage> for NetfilterMessageInner {
77    fn from(message: NfConntrackMessage) -> Self {
78        Self::NfConntrack(message)
79    }
80}
81
82impl From<NfLogMessage> for NetfilterMessageInner {
83    fn from(message: NfLogMessage) -> Self {
84        Self::NfLog(message)
85    }
86}
87
88impl Emitable for NetfilterMessageInner {
89    fn buffer_len(&self) -> usize {
90        match self {
91            NetfilterMessageInner::NfConntrack(msg) => msg.buffer_len(),
92            NetfilterMessageInner::NfLog(msg) => msg.buffer_len(),
93            NetfilterMessageInner::Other { nlas, .. } => {
94                nlas.as_slice().buffer_len()
95            }
96        }
97    }
98
99    fn emit(&self, buffer: &mut [u8]) {
100        match self {
101            NetfilterMessageInner::NfConntrack(msg) => msg.emit(buffer),
102            NetfilterMessageInner::NfLog(msg) => msg.emit(buffer),
103            NetfilterMessageInner::Other { nlas, .. } => {
104                nlas.as_slice().emit(buffer)
105            }
106        }
107    }
108}
109
110#[derive(Debug, PartialEq, Eq, Clone)]
111pub struct NetfilterMessage {
112    pub header: NetfilterHeader,
113    pub inner: NetfilterMessageInner,
114}
115
116impl NetfilterMessage {
117    pub fn new<T: Into<NetfilterMessageInner>>(
118        header: NetfilterHeader,
119        inner: T,
120    ) -> Self {
121        Self {
122            header,
123            inner: inner.into(),
124        }
125    }
126
127    pub fn subsys(&self) -> u8 {
128        match self.inner {
129            NetfilterMessageInner::NfConntrack(_) => NfConntrackMessage::SUBSYS,
130            NetfilterMessageInner::NfLog(_) => NfLogMessage::SUBSYS,
131            NetfilterMessageInner::Other { subsys, .. } => subsys,
132        }
133    }
134
135    pub fn message_type(&self) -> u8 {
136        match self.inner {
137            NetfilterMessageInner::NfConntrack(ref msg) => msg.message_type(),
138            NetfilterMessageInner::NfLog(ref msg) => msg.message_type(),
139            NetfilterMessageInner::Other { message_type, .. } => message_type,
140        }
141    }
142}
143
144impl Emitable for NetfilterMessage {
145    fn buffer_len(&self) -> usize {
146        self.header.buffer_len() + self.inner.buffer_len()
147    }
148
149    fn emit(&self, buffer: &mut [u8]) {
150        self.header.emit(buffer);
151        self.inner.emit(&mut buffer[self.header.buffer_len()..]);
152    }
153}
154
155impl NetlinkSerializable for NetfilterMessage {
156    fn message_type(&self) -> u16 {
157        ((self.subsys() as u16) << 8) | self.message_type() as u16
158    }
159
160    fn buffer_len(&self) -> usize {
161        <Self as Emitable>::buffer_len(self)
162    }
163
164    fn serialize(&self, buffer: &mut [u8]) {
165        self.emit(buffer)
166    }
167}
168
169impl NetlinkDeserializable for NetfilterMessage {
170    type Error = DecodeError;
171    fn deserialize(
172        header: &NetlinkHeader,
173        payload: &[u8],
174    ) -> Result<Self, Self::Error> {
175        match NetfilterBuffer::new_checked(payload) {
176            Err(e) => Err(e),
177            Ok(buffer) => match NetfilterMessage::parse_with_param(
178                &buffer,
179                header.message_type,
180            ) {
181                Err(e) => Err(e),
182                Ok(message) => Ok(message),
183            },
184        }
185    }
186}
187
188impl From<NetfilterMessage> for NetlinkPayload<NetfilterMessage> {
189    fn from(message: NetfilterMessage) -> Self {
190        NetlinkPayload::InnerMessage(message)
191    }
192}