1use std::{
19 error::Error,
20 fmt::{self, Debug, Display},
21 io::{self, Cursor, ErrorKind},
22 str::Utf8Error,
23 string::FromUtf8Error,
24 sync::Arc,
25};
26
27use derive_builder::{Builder, UninitializedFieldError};
28use getset::Getters;
29
30use crate::{
31 self as neli, FromBytes, FromBytesWithInput, Header, Size, ToBytes, TypeSize,
32 consts::nl::{NlType, NlmF, NlmsgerrAttr},
33 genl::{AttrTypeBuilderError, GenlmsghdrBuilderError, NlattrBuilderError},
34 nl::{Nlmsghdr, NlmsghdrBuilderError},
35 rtnl::{
36 IfaddrmsgBuilderError, IfinfomsgBuilderError, NdaCacheinfoBuilderError, NdmsgBuilderError,
37 RtattrBuilderError, RtgenmsgBuilderError, RtmsgBuilderError, TcmsgBuilderError,
38 },
39 types::{Buffer, GenlBuffer},
40};
41
42#[derive(Builder, Getters, Clone, Debug, PartialEq, Eq, Size, ToBytes, FromBytes)]
45#[neli(header_bound = "T: TypeSize")]
46#[neli(from_bytes_bound = "T: NlType")]
47#[builder(pattern = "owned")]
48pub struct NlmsghdrAck<T> {
49 #[getset(get = "pub")]
51 nl_len: u32,
52 #[getset(get = "pub")]
54 nl_type: T,
55 #[getset(get = "pub")]
57 nl_flags: NlmF,
58 #[getset(get = "pub")]
60 nl_seq: u32,
61 #[getset(get = "pub")]
64 nl_pid: u32,
65}
66
67impl NlmsghdrAck<u16> {
68 pub fn to_typed<T, P>(self) -> Result<NlmsghdrAck<T>, RouterError<T, P>>
70 where
71 T: NlType,
72 {
73 Ok(NlmsghdrAckBuilder::default()
74 .nl_len(self.nl_len)
75 .nl_type(T::from(self.nl_type))
76 .nl_flags(self.nl_flags)
77 .nl_seq(self.nl_seq)
78 .nl_pid(self.nl_pid)
79 .build()?)
80 }
81}
82
83#[derive(Builder, Getters, Clone, Debug, PartialEq, Eq, Size, ToBytes, FromBytes, Header)]
86#[neli(header_bound = "T: TypeSize")]
87#[neli(from_bytes_bound = "T: NlType + TypeSize")]
88#[neli(from_bytes_bound = "P: FromBytesWithInput<Input = usize>")]
89#[builder(build_fn(skip))]
90#[builder(pattern = "owned")]
91pub struct NlmsghdrErr<T, P> {
92 #[getset(get = "pub")]
94 #[builder(setter(skip))]
95 nl_len: u32,
96 #[getset(get = "pub")]
98 nl_type: T,
99 #[getset(get = "pub")]
101 nl_flags: NlmF,
102 #[getset(get = "pub")]
104 nl_seq: u32,
105 #[getset(get = "pub")]
108 nl_pid: u32,
109 #[neli(input = "nl_len as usize - Self::header_size()")]
111 #[getset(get = "pub")]
112 nl_payload: P,
113}
114
115impl<T, P> NlmsghdrErrBuilder<T, P>
116where
117 T: NlType,
118 P: Size + FromBytesWithInput<Input = usize>,
119{
120 pub fn build(self) -> Result<NlmsghdrErr<T, P>, NlmsghdrErrBuilderError> {
122 let nl_type = self.nl_type.ok_or_else(|| {
123 NlmsghdrErrBuilderError::from(UninitializedFieldError::new("nl_type"))
124 })?;
125 let nl_flags = self.nl_flags.unwrap_or(NlmF::empty());
126 let nl_seq = self.nl_seq.unwrap_or(0);
127 let nl_pid = self.nl_pid.unwrap_or(0);
128 let nl_payload = self.nl_payload.ok_or_else(|| {
129 NlmsghdrErrBuilderError::from(UninitializedFieldError::new("nl_payload"))
130 })?;
131
132 let mut nl = NlmsghdrErr {
133 nl_len: 0,
134 nl_type,
135 nl_flags,
136 nl_seq,
137 nl_pid,
138 nl_payload,
139 };
140 nl.nl_len = nl.padded_size() as u32;
141 Ok(nl)
142 }
143}
144
145impl NlmsghdrErr<u16, Buffer> {
146 pub fn to_typed<T, P>(self) -> Result<NlmsghdrErr<T, P>, RouterError<T, P>>
148 where
149 T: NlType,
150 P: Size + FromBytesWithInput<Input = usize>,
151 {
152 Ok(NlmsghdrErrBuilder::default()
153 .nl_type(T::from(self.nl_type))
154 .nl_flags(self.nl_flags)
155 .nl_seq(self.nl_seq)
156 .nl_pid(self.nl_pid)
157 .nl_payload(P::from_bytes_with_input(
158 &mut Cursor::new(self.nl_payload),
159 self.nl_len as usize - Self::header_size(),
160 )?)
161 .build()?)
162 }
163}
164
165#[derive(Builder, Getters, Clone, Debug, PartialEq, Eq, Size, FromBytesWithInput, ToBytes)]
167#[neli(from_bytes_bound = "M: Size + FromBytes")]
168#[builder(pattern = "owned")]
169pub struct Nlmsgerr<M> {
170 #[builder(default = "0")]
172 #[getset(get = "pub")]
173 error: libc::c_int,
174 #[getset(get = "pub")]
176 #[neli(skip_debug)]
177 nlmsg: M,
178 #[neli(input = "input - error.padded_size() - nlmsg.padded_size()")]
179 #[builder(default = "GenlBuffer::new()")]
181 #[getset(get = "pub")]
182 ext_ack: GenlBuffer<NlmsgerrAttr, Buffer>,
183}
184
185impl<M> Display for Nlmsgerr<M> {
186 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
187 write!(f, "{}", io::Error::from_raw_os_error(-self.error))
188 }
189}
190
191impl<M> Error for Nlmsgerr<M> where M: Debug {}
192
193impl Nlmsgerr<NlmsghdrErr<u16, Buffer>> {
194 pub fn to_typed<T, P>(self) -> Result<Nlmsgerr<NlmsghdrErr<T, P>>, RouterError<T, P>>
196 where
197 T: NlType,
198 P: Size + FromBytesWithInput<Input = usize>,
199 {
200 Ok(NlmsgerrBuilder::default()
201 .error(self.error)
202 .nlmsg(self.nlmsg.to_typed()?)
203 .build()?)
204 }
205}
206
207impl Nlmsgerr<NlmsghdrAck<u16>> {
208 pub fn to_typed<T, P>(self) -> Result<Nlmsgerr<NlmsghdrAck<T>>, RouterError<T, P>>
210 where
211 T: NlType,
212 {
213 Ok(NlmsgerrBuilder::default()
214 .error(self.error)
215 .nlmsg(self.nlmsg.to_typed()?)
216 .build()?)
217 }
218}
219
220#[derive(Debug)]
221#[allow(missing_docs)]
222pub enum BuilderError {
223 #[allow(missing_docs)]
224 Nlmsghdr(NlmsghdrBuilderError),
225 #[allow(missing_docs)]
226 Nlmsgerr(NlmsgerrBuilderError),
227 #[allow(missing_docs)]
228 NlmsghdrErr(NlmsghdrErrBuilderError),
229 #[allow(missing_docs)]
230 Genlmsghdr(GenlmsghdrBuilderError),
231 #[allow(missing_docs)]
232 Nlattr(NlattrBuilderError),
233 #[allow(missing_docs)]
234 AttrType(AttrTypeBuilderError),
235 #[allow(missing_docs)]
236 Ifinfomsg(IfinfomsgBuilderError),
237 #[allow(missing_docs)]
238 Ifaddrmsg(IfaddrmsgBuilderError),
239 #[allow(missing_docs)]
240 Rtgenmsg(RtgenmsgBuilderError),
241 #[allow(missing_docs)]
242 Rtmsg(RtmsgBuilderError),
243 #[allow(missing_docs)]
244 Ndmsg(NdmsgBuilderError),
245 #[allow(missing_docs)]
246 NdaCacheinfo(NdaCacheinfoBuilderError),
247 #[allow(missing_docs)]
248 Tcmsg(TcmsgBuilderError),
249 #[allow(missing_docs)]
250 Rtattr(RtattrBuilderError),
251 #[allow(missing_docs)]
252 NlmsghdrAck(NlmsghdrAckBuilderError),
253}
254
255impl Error for BuilderError {}
256
257impl Display for BuilderError {
258 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
259 match self {
260 BuilderError::Nlmsghdr(err) => write!(f, "{err}"),
261 BuilderError::Nlmsgerr(err) => write!(f, "{err}"),
262 BuilderError::NlmsghdrErr(err) => write!(f, "{err}"),
263 BuilderError::Genlmsghdr(err) => write!(f, "{err}"),
264 BuilderError::Nlattr(err) => write!(f, "{err}"),
265 BuilderError::AttrType(err) => write!(f, "{err}"),
266 BuilderError::Ifinfomsg(err) => write!(f, "{err}"),
267 BuilderError::Ifaddrmsg(err) => write!(f, "{err}"),
268 BuilderError::Rtgenmsg(err) => write!(f, "{err}"),
269 BuilderError::Rtmsg(err) => write!(f, "{err}"),
270 BuilderError::Ndmsg(err) => write!(f, "{err}"),
271 BuilderError::NdaCacheinfo(err) => write!(f, "{err}"),
272 BuilderError::Tcmsg(err) => write!(f, "{err}"),
273 BuilderError::Rtattr(err) => write!(f, "{err}"),
274 BuilderError::NlmsghdrAck(err) => write!(f, "{err}"),
275 }
276 }
277}
278
279impl From<NlmsghdrBuilderError> for BuilderError {
280 fn from(e: NlmsghdrBuilderError) -> Self {
281 BuilderError::Nlmsghdr(e)
282 }
283}
284
285impl From<NlmsgerrBuilderError> for BuilderError {
286 fn from(e: NlmsgerrBuilderError) -> Self {
287 BuilderError::Nlmsgerr(e)
288 }
289}
290
291impl From<NlmsghdrErrBuilderError> for BuilderError {
292 fn from(e: NlmsghdrErrBuilderError) -> Self {
293 BuilderError::NlmsghdrErr(e)
294 }
295}
296
297impl From<GenlmsghdrBuilderError> for BuilderError {
298 fn from(e: GenlmsghdrBuilderError) -> Self {
299 BuilderError::Genlmsghdr(e)
300 }
301}
302
303impl From<NlattrBuilderError> for BuilderError {
304 fn from(e: NlattrBuilderError) -> Self {
305 BuilderError::Nlattr(e)
306 }
307}
308
309impl From<AttrTypeBuilderError> for BuilderError {
310 fn from(e: AttrTypeBuilderError) -> Self {
311 BuilderError::AttrType(e)
312 }
313}
314
315impl From<IfinfomsgBuilderError> for BuilderError {
316 fn from(e: IfinfomsgBuilderError) -> Self {
317 BuilderError::Ifinfomsg(e)
318 }
319}
320
321impl From<IfaddrmsgBuilderError> for BuilderError {
322 fn from(e: IfaddrmsgBuilderError) -> Self {
323 BuilderError::Ifaddrmsg(e)
324 }
325}
326
327impl From<RtgenmsgBuilderError> for BuilderError {
328 fn from(e: RtgenmsgBuilderError) -> Self {
329 BuilderError::Rtgenmsg(e)
330 }
331}
332
333impl From<RtmsgBuilderError> for BuilderError {
334 fn from(e: RtmsgBuilderError) -> Self {
335 BuilderError::Rtmsg(e)
336 }
337}
338
339impl From<NdmsgBuilderError> for BuilderError {
340 fn from(e: NdmsgBuilderError) -> Self {
341 BuilderError::Ndmsg(e)
342 }
343}
344
345impl From<NdaCacheinfoBuilderError> for BuilderError {
346 fn from(e: NdaCacheinfoBuilderError) -> Self {
347 BuilderError::NdaCacheinfo(e)
348 }
349}
350
351impl From<TcmsgBuilderError> for BuilderError {
352 fn from(e: TcmsgBuilderError) -> Self {
353 BuilderError::Tcmsg(e)
354 }
355}
356
357impl From<RtattrBuilderError> for BuilderError {
358 fn from(e: RtattrBuilderError) -> Self {
359 BuilderError::Rtattr(e)
360 }
361}
362
363impl From<NlmsghdrAckBuilderError> for BuilderError {
364 fn from(e: NlmsghdrAckBuilderError) -> Self {
365 BuilderError::NlmsghdrAck(e)
366 }
367}
368
369#[derive(Clone, Debug)]
372pub enum RouterError<T, P> {
373 Msg(MsgError),
375 Io(ErrorKind),
377 De(DeError),
379 Socket(SocketError),
381 Nlmsgerr(Nlmsgerr<NlmsghdrErr<T, P>>),
383 BadSeqOrPid(Nlmsghdr<T, P>),
385 NoAck,
389 UnexpectedAck,
393 ClosedChannel,
395}
396
397impl<T, P> RouterError<T, P> {
398 pub fn new<D>(d: D) -> Self
400 where
401 D: Display,
402 {
403 RouterError::Msg(MsgError::new(d.to_string()))
404 }
405}
406
407impl RouterError<u16, Buffer> {
408 pub fn to_typed<T, P>(self) -> Result<RouterError<T, P>, RouterError<T, P>>
410 where
411 T: NlType,
412 P: Size + FromBytesWithInput<Input = usize>,
413 {
414 match self {
415 RouterError::Msg(msg) => Ok(RouterError::Msg(msg)),
416 RouterError::Io(kind) => Ok(RouterError::Io(kind)),
417 RouterError::De(err) => Ok(RouterError::De(err)),
418 RouterError::Socket(err) => Ok(RouterError::Socket(err)),
419 RouterError::Nlmsgerr(err) => Ok(RouterError::Nlmsgerr(err.to_typed()?)),
420 RouterError::BadSeqOrPid(msg) => Ok(RouterError::BadSeqOrPid(msg.to_typed()?)),
421 RouterError::NoAck => Ok(RouterError::NoAck),
422 RouterError::UnexpectedAck => Ok(RouterError::UnexpectedAck),
423 RouterError::ClosedChannel => Ok(RouterError::ClosedChannel),
424 }
425 }
426}
427
428impl<T, P> Display for RouterError<T, P>
429where
430 T: Debug,
431 P: Debug,
432{
433 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
434 match self {
435 RouterError::Msg(msg) => write!(f, "{msg}"),
436 RouterError::Io(kind) => write!(f, "IO error: {kind}"),
437 RouterError::De(err) => write!(f, "Deserialization failed: {err}"),
438 RouterError::Socket(err) => write!(f, "Socket error: {err}"),
439 RouterError::Nlmsgerr(msg) => {
440 write!(f, "Application error was returned by netlink: {msg:?}")
441 }
442 RouterError::BadSeqOrPid(msg) => {
443 write!(f, "A bad sequence number or PID was received: {msg:?}")
444 }
445 RouterError::NoAck => write!(f, "No ACK received"),
446 RouterError::UnexpectedAck => write!(f, "ACK received when none was expected"),
447 RouterError::ClosedChannel => {
448 write!(f, "A channel required for message processing closed")
449 }
450 }
451 }
452}
453
454impl<E, T, P> From<E> for RouterError<T, P>
455where
456 BuilderError: From<E>,
457{
458 fn from(e: E) -> Self {
459 RouterError::new(BuilderError::from(e).to_string())
460 }
461}
462
463impl<T, P> From<DeError> for RouterError<T, P> {
464 fn from(e: DeError) -> Self {
465 RouterError::De(e)
466 }
467}
468
469impl<T, P> From<SocketError> for RouterError<T, P> {
470 fn from(e: SocketError) -> Self {
471 RouterError::Socket(e)
472 }
473}
474
475impl<T, P> From<MsgError> for RouterError<T, P> {
476 fn from(e: MsgError) -> Self {
477 RouterError::Msg(e)
478 }
479}
480
481impl<T, P> Error for RouterError<T, P>
482where
483 T: Debug,
484 P: Debug,
485{
486}
487
488#[derive(Clone, Debug)]
490pub enum SocketError {
491 Msg(MsgError),
493 Ser(SerError),
495 De(DeError),
497 Io(Arc<io::Error>),
499}
500
501impl From<SerError> for SocketError {
502 fn from(err: SerError) -> Self {
503 SocketError::Ser(err)
504 }
505}
506
507impl From<DeError> for SocketError {
508 fn from(err: DeError) -> Self {
509 SocketError::De(err)
510 }
511}
512
513impl From<io::Error> for SocketError {
514 fn from(err: io::Error) -> Self {
515 SocketError::Io(Arc::new(err))
516 }
517}
518
519impl<E> From<E> for SocketError
520where
521 BuilderError: From<E>,
522{
523 fn from(err: E) -> Self {
524 SocketError::new(BuilderError::from(err).to_string())
525 }
526}
527
528impl From<MsgError> for SocketError {
529 fn from(e: MsgError) -> Self {
530 SocketError::Msg(e)
531 }
532}
533
534impl SocketError {
535 pub fn new<D>(s: D) -> Self
538 where
539 D: Display,
540 {
541 SocketError::Msg(MsgError::new(s))
542 }
543}
544
545impl Display for SocketError {
546 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
547 match *self {
548 SocketError::Msg(ref msg) => write!(f, "{msg}"),
549 SocketError::Ser(ref err) => {
550 write!(f, "Serialization error: {err}")
551 }
552 SocketError::De(ref err) => {
553 write!(f, "Deserialization error: {err}")
554 }
555 SocketError::Io(ref err) => {
556 write!(f, "IO error: {err}")
557 }
558 }
559 }
560}
561
562impl Error for SocketError {}
563
564#[derive(Clone, Debug)]
566pub enum Utf8 {
567 #[allow(missing_docs)]
568 Str(Utf8Error),
569 #[allow(missing_docs)]
570 String(FromUtf8Error),
571}
572
573impl Display for Utf8 {
574 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
575 match self {
576 Utf8::Str(e) => write!(f, "{e}"),
577 Utf8::String(e) => write!(f, "{e}"),
578 }
579 }
580}
581
582#[derive(Clone, Debug)]
584pub enum SerError {
585 Msg(MsgError),
587 Io(ErrorKind),
589 Utf8(Utf8),
591}
592
593impl SerError {
594 pub fn new<D>(msg: D) -> Self
596 where
597 D: Display,
598 {
599 SerError::Msg(MsgError::new(msg))
600 }
601}
602
603impl Display for SerError {
604 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
605 match self {
606 SerError::Msg(s) => write!(f, "{s}"),
607 SerError::Io(err) => write!(f, "IO error: {err}"),
608 SerError::Utf8(err) => write!(f, "UTF error: {err}"),
609 }
610 }
611}
612
613impl Error for SerError {}
614
615impl From<io::Error> for SerError {
616 fn from(err: io::Error) -> Self {
617 SerError::Io(err.kind())
618 }
619}
620
621impl From<Utf8Error> for SerError {
622 fn from(err: Utf8Error) -> Self {
623 SerError::Utf8(Utf8::Str(err))
624 }
625}
626
627impl From<FromUtf8Error> for SerError {
628 fn from(err: FromUtf8Error) -> Self {
629 SerError::Utf8(Utf8::String(err))
630 }
631}
632
633impl From<MsgError> for SerError {
634 fn from(e: MsgError) -> Self {
635 SerError::Msg(e)
636 }
637}
638
639#[derive(Clone, Debug)]
641pub enum DeError {
642 Msg(MsgError),
644 Io(ErrorKind),
646 Utf8(Utf8),
648 InvalidInput(usize),
650}
651
652impl DeError {
653 pub fn new<D>(s: D) -> Self
656 where
657 D: Display,
658 {
659 DeError::Msg(MsgError::new(s))
660 }
661}
662
663impl Display for DeError {
664 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
665 match self {
666 DeError::Msg(s) => write!(f, "{s}"),
667 DeError::Utf8(err) => write!(f, "UTF8 error: {err}"),
668 DeError::Io(err) => write!(f, "IO error: {err}"),
669 DeError::InvalidInput(input) => write!(f, "Invalid input was provided: {input}"),
670 }
671 }
672}
673
674impl Error for DeError {}
675
676impl From<io::Error> for DeError {
677 fn from(err: io::Error) -> Self {
678 DeError::Io(err.kind())
679 }
680}
681
682impl From<Utf8Error> for DeError {
683 fn from(err: Utf8Error) -> Self {
684 DeError::Utf8(Utf8::Str(err))
685 }
686}
687
688impl From<FromUtf8Error> for DeError {
689 fn from(err: FromUtf8Error) -> Self {
690 DeError::Utf8(Utf8::String(err))
691 }
692}
693
694impl<E> From<E> for DeError
695where
696 BuilderError: From<E>,
697{
698 fn from(err: E) -> Self {
699 DeError::new(BuilderError::from(err).to_string())
700 }
701}
702
703impl From<MsgError> for DeError {
704 fn from(e: MsgError) -> Self {
705 DeError::Msg(e)
706 }
707}
708
709#[derive(Clone, Debug)]
711pub struct MsgError(String);
712
713impl MsgError {
714 pub fn new<D>(d: D) -> Self
716 where
717 D: Display,
718 {
719 MsgError(d.to_string())
720 }
721}
722
723impl Display for MsgError {
724 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
725 write!(f, "{}", self.0)
726 }
727}
728
729impl Error for MsgError {}