1use crate as neli;
25
26use std::{
27 error::Error,
28 fmt::{self, Debug, Display},
29 io, str, string,
30};
31
32use crate::{
33 consts::nl::{NlType, NlmFFlags},
34 types::Buffer,
35 FromBytes, FromBytesWithInput, Header, Size, ToBytes, TypeSize,
36};
37
38#[derive(Debug, PartialEq, Eq, Size, ToBytes, FromBytesWithInput, Header)]
45#[neli(header_bound = "T: TypeSize")]
46#[neli(from_bytes_bound = "T: TypeSize + FromBytes")]
47#[neli(from_bytes_bound = "P: FromBytesWithInput<Input = usize>")]
48pub struct NlmsghdrErr<T, P> {
49 pub nl_len: u32,
51 pub nl_type: T,
53 pub nl_flags: NlmFFlags,
55 pub nl_seq: u32,
57 pub nl_pid: u32,
60 #[neli(input = "input - Self::header_size()")]
62 pub nl_payload: P,
63}
64
65#[derive(Debug, PartialEq, Eq, Size, FromBytesWithInput, ToBytes, Header)]
67#[neli(from_bytes_bound = "T: NlType")]
68#[neli(from_bytes_bound = "P: FromBytesWithInput<Input = usize>")]
69pub struct Nlmsgerr<T, P> {
70 pub error: libc::c_int,
72 #[neli(input = "input - Self::header_size()")]
74 pub nlmsg: NlmsghdrErr<T, P>,
75}
76
77impl<T, P> Display for Nlmsgerr<T, P> {
78 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
79 write!(f, "{}", io::Error::from_raw_os_error(-self.error))
80 }
81}
82
83impl<T, P> Error for Nlmsgerr<T, P>
84where
85 T: Debug,
86 P: Debug,
87{
88}
89
90macro_rules! err_from {
91 ($err:ident, $($from_err:path { $from_impl:expr }),+) => {
92 $(
93 impl From<$from_err> for $err {
94 fn from(e: $from_err) -> Self {
95 $from_impl(e)
96 }
97 }
98 )*
99 };
100}
101
102#[derive(Debug)]
104pub enum NlError<T = u16, P = Buffer> {
105 Msg(String),
107 Nlmsgerr(Nlmsgerr<T, P>),
109 Ser(SerError),
111 De(DeError),
113 Wrapped(WrappedError),
115 NoAck,
119 BadSeq,
122 BadPid,
124}
125
126impl<T, P> From<Nlmsgerr<T, P>> for NlError<T, P> {
127 fn from(err: Nlmsgerr<T, P>) -> Self {
128 NlError::Nlmsgerr(err)
129 }
130}
131
132impl<T, P> From<SerError> for NlError<T, P> {
133 fn from(err: SerError) -> Self {
134 NlError::Ser(err)
135 }
136}
137
138impl<T, P> From<DeError> for NlError<T, P> {
139 fn from(err: DeError) -> Self {
140 NlError::De(err)
141 }
142}
143
144impl<T, P> From<io::Error> for NlError<T, P> {
145 fn from(err: io::Error) -> Self {
146 NlError::Wrapped(WrappedError::IOError(err))
147 }
148}
149
150err_from!(
151 NlError,
152 WrappedError { NlError::Wrapped },
153 std::str::Utf8Error { |e| NlError::Wrapped(WrappedError::from(e)) },
154 std::string::FromUtf8Error { |e| NlError::Wrapped(WrappedError::from(e)) },
155 std::ffi::FromBytesWithNulError { |e| NlError::Wrapped(WrappedError::from(e)) }
156);
157
158impl NlError {
159 pub fn msg<D>(s: D) -> Self
162 where
163 D: Display,
164 {
165 NlError::Msg(s.to_string())
166 }
167}
168
169impl<T, P> NlError<T, P> {
170 pub fn new<D>(s: D) -> Self
173 where
174 D: Display,
175 {
176 NlError::Msg(s.to_string())
177 }
178}
179
180impl<T, P> Display for NlError<T, P>
181where
182 T: Debug,
183 P: Debug,
184{
185 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
186 match *self {
187 NlError::Msg(ref msg) => write!(f, "{}", msg),
188 NlError::Nlmsgerr(ref err) => {
189 write!(f, "Error response received from netlink: {}", err)
190 }
191 NlError::Ser(ref err) => {
192 write!(f, "Serialization error: {}", err)
193 }
194 NlError::De(ref err) => {
195 write!(f, "Deserialization error: {}", err)
196 }
197 NlError::NoAck => write!(f, "No ack received"),
198 NlError::BadSeq => write!(f, "Sequence number does not match the request"),
199 NlError::BadPid => write!(f, "PID does not match the socket"),
200 NlError::Wrapped(ref e) => write!(f, "Netlink failure due to error: {}", e),
201 }
202 }
203}
204
205impl<T, P> Error for NlError<T, P>
206where
207 T: Debug,
208 P: Debug,
209{
210}
211
212#[derive(Debug)]
214pub enum SerError {
215 Msg(String),
217 Wrapped(WrappedError),
219 UnexpectedEOB,
221 BufferNotFilled,
223}
224
225err_from!(
226 SerError,
227 WrappedError { SerError::Wrapped },
228 std::io::Error { |e| SerError::Wrapped(WrappedError::from(e)) },
229 std::str::Utf8Error { |e| SerError::Wrapped(WrappedError::from(e)) },
230 std::string::FromUtf8Error { |e| SerError::Wrapped(WrappedError::from(e)) },
231 std::ffi::FromBytesWithNulError { |e| SerError::Wrapped(WrappedError::from(e)) }
232);
233
234impl SerError {
235 pub fn new<D>(msg: D) -> Self
237 where
238 D: Display,
239 {
240 SerError::Msg(msg.to_string())
241 }
242}
243
244impl Display for SerError {
245 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
246 match self {
247 SerError::Msg(ref s) => write!(f, "{}", s),
248 SerError::Wrapped(ref e) => write!(f, "Error while serializing: {}", e),
249 SerError::UnexpectedEOB => write!(
250 f,
251 "The buffer was too small for the requested serialization operation",
252 ),
253 SerError::BufferNotFilled => write!(
254 f,
255 "The number of bytes written to the buffer did not fill the \
256 given space",
257 ),
258 }
259 }
260}
261
262impl Error for SerError {}
263
264err_from!(
265 DeError,
266 WrappedError { DeError::Wrapped },
267 std::io::Error { |e| DeError::Wrapped(WrappedError::from(e)) },
268 std::str::Utf8Error { |e| DeError::Wrapped(WrappedError::from(e)) },
269 std::string::FromUtf8Error { |e| DeError::Wrapped(WrappedError::from(e)) },
270 std::ffi::FromBytesWithNulError { |e| DeError::Wrapped(WrappedError::from(e)) }
271);
272
273#[derive(Debug)]
275pub enum DeError {
276 Msg(String),
278 Wrapped(WrappedError),
280 UnexpectedEOB,
283 BufferNotParsed,
285 NullError,
288 NoNullError,
291}
292
293impl DeError {
294 pub fn new<D>(s: D) -> Self
297 where
298 D: Display,
299 {
300 DeError::Msg(s.to_string())
301 }
302}
303
304impl Display for DeError {
305 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
306 match *self {
307 DeError::Msg(ref s) => write!(f, "{}", s),
308 DeError::UnexpectedEOB => write!(
309 f,
310 "The buffer was not large enough to complete the deserialize \
311 operation",
312 ),
313 DeError::BufferNotParsed => write!(f, "Unparsed data left in buffer"),
314 DeError::NullError => write!(f, "A null was found before the end of the buffer"),
315 DeError::NoNullError => write!(f, "No terminating null byte was found in the buffer"),
316 DeError::Wrapped(ref e) => write!(f, "Error while deserializing: {}", e),
317 }
318 }
319}
320
321impl Error for DeError {}
322
323#[derive(Debug)]
326pub enum WrappedError {
327 IOError(io::Error),
329 StrUtf8Error(str::Utf8Error),
331 StringUtf8Error(string::FromUtf8Error),
333 FFINullError(std::ffi::FromBytesWithNulError),
335}
336
337impl Display for WrappedError {
338 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
339 match *self {
340 WrappedError::IOError(ref e) => write!(f, "Wrapped IO error: {}", e),
341 WrappedError::StrUtf8Error(ref e) => write!(f, "Wrapped &str error: {}", e),
342 WrappedError::StringUtf8Error(ref e) => write!(f, "Wrapped String error: {}", e),
343 WrappedError::FFINullError(ref e) => write!(f, "Wrapped null error: {}", e),
344 }
345 }
346}
347
348impl Error for WrappedError {}
349
350macro_rules! wrapped_err_from {
351 ($($var:ident => $from_err_name:path),*) => {
352 $(
353 impl From<$from_err_name> for WrappedError {
354 fn from(v: $from_err_name) -> Self {
355 WrappedError::$var(v)
356 }
357 }
358 )*
359 }
360}
361
362wrapped_err_from!(
363 IOError => std::io::Error,
364 StrUtf8Error => std::str::Utf8Error,
365 StringUtf8Error => std::string::FromUtf8Error,
366 FFINullError => std::ffi::FromBytesWithNulError
367);