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