reyzell_netlink_packet_netfilter/
message.rs1use 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}