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::{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}