Skip to main content

r_lanlib/
error.rs

1//! Custom Error and Result types for this library
2
3use std::{
4    any::Any,
5    num::ParseIntError,
6    sync::{
7        MutexGuard, PoisonError,
8        mpsc::{RecvError, SendError},
9    },
10};
11use thiserror::Error;
12
13use crate::{
14    packet::{
15        Reader, Sender, arp_packet::ArpPacketBuilderError,
16        heartbeat_packet::HeartbeatPacketBuilderError,
17        rst_packet::RstPacketBuilderError, syn_packet::SynPacketBuilderError,
18    },
19    scanners::{
20        ScanMessage, arp_scanner::ARPScannerBuilderError,
21        heartbeat::HeartBeatBuilderError, syn_scanner::SYNScannerBuilderError,
22    },
23};
24
25/// Custom Error type for this library
26#[derive(Error, Debug)]
27pub enum RLanLibError {
28    /// Error coming directly off the wire
29    #[error("wire error: {_0}")]
30    Wire(String),
31
32    /// Errors resulting from events channel
33    #[error("failed to send notification message: {:#?}", _0)]
34    NotifierSendError(#[from] SendError<Box<ScanMessage>>),
35
36    /// Error obtaining lock on packet reader
37    #[error("failed to get lock on packet reader: {_0}")]
38    PacketReaderLock(String),
39
40    /// Error obtaining lock on packet sender
41    #[error("failed to get lock on packet sender: {_0}")]
42    PacketSenderLock(String),
43
44    /// Generic thread error
45    #[error("thread error: {_0}")]
46    ThreadError(String),
47
48    /// Errors when consuming messages from channels
49    #[error("failed to receive message from channel: {:#?}", _0)]
50    ChannelReceive(#[from] RecvError),
51
52    /// Error generated during ARP packet construction
53    #[error("failed to build ARP packet: {_0}")]
54    ArpPacketBuild(#[from] ArpPacketBuilderError),
55
56    /// Error resulting from failure to build ARP scanner
57    #[error("failed to build arp scanner: {_0}")]
58    ArpScannerBuild(#[from] ARPScannerBuilderError),
59
60    /// Error resulting from failure to build SYN scanner
61    #[error("failed to build syn scanner: {_0}")]
62    SynScannerBuild(#[from] SYNScannerBuilderError),
63
64    /// Error resulting from failure to build Heartbeat
65    #[error("failed to build heartbeat: {_0}")]
66    HeartBeatBuild(#[from] HeartBeatBuilderError),
67
68    /// Error generated during RST packet construction
69    #[error("failed to build RST packet: {_0}")]
70    RstPacketBuild(#[from] RstPacketBuilderError),
71
72    /// Error generated during SYN packet construction
73    #[error("failed to build SYN packet: {_0}")]
74    SynPacketBuild(#[from] SynPacketBuilderError),
75
76    /// Error generated during heartbeat packet construction
77    #[error("failed to build heartbeat packet: {_0}")]
78    HeartbeatPacketBuild(#[from] HeartbeatPacketBuilderError),
79
80    /// Wrapping errors related to scanning
81    #[error("scanning error: {error} - ip: {:#?}, port: {:#?}", ip, port)]
82    Scan {
83        /// The error message encountered
84        error: String,
85        /// The associated IP address being scanned
86        ip: Option<String>,
87        /// The associated port being scanned
88        port: Option<String>,
89    },
90}
91
92impl From<Box<dyn Any + Send>> for RLanLibError {
93    fn from(value: Box<dyn Any + Send>) -> Self {
94        if let Some(s) = value.downcast_ref::<&'static str>() {
95            Self::ThreadError(format!("Thread panicked with: {}", s))
96        } else if let Some(s) = value.downcast_ref::<String>() {
97            Self::ThreadError(format!("Thread panicked with: {}", s))
98        } else {
99            Self::ThreadError("Thread panicked with an unknown type".into())
100        }
101    }
102}
103
104impl<'a> From<PoisonError<MutexGuard<'a, dyn Reader + 'static>>>
105    for RLanLibError
106{
107    fn from(value: PoisonError<MutexGuard<'a, dyn Reader + 'static>>) -> Self {
108        Self::PacketReaderLock(value.to_string())
109    }
110}
111
112impl<'a> From<PoisonError<MutexGuard<'a, dyn Sender + 'static>>>
113    for RLanLibError
114{
115    fn from(value: PoisonError<MutexGuard<'a, dyn Sender + 'static>>) -> Self {
116        Self::PacketSenderLock(value.to_string())
117    }
118}
119
120impl RLanLibError {
121    /// Converter for std::net::AddrParseError
122    pub fn from_net_addr_parse_error(
123        ip: &str,
124        error: std::net::AddrParseError,
125    ) -> Self {
126        Self::Scan {
127            error: error.to_string(),
128            ip: Some(ip.to_string()),
129            port: None,
130        }
131    }
132
133    /// Converter for ipnet::AddrParseError
134    pub fn from_ipnet_addr_parse_error(
135        ip: &str,
136        error: ipnet::AddrParseError,
137    ) -> Self {
138        Self::Scan {
139            error: error.to_string(),
140            ip: Some(ip.to_string()),
141            port: None,
142        }
143    }
144
145    /// Converter for ParseIntError
146    pub fn from_port_parse_int_err(port: &str, error: ParseIntError) -> Self {
147        Self::Scan {
148            error: error.to_string(),
149            ip: None,
150            port: Some(port.to_string()),
151        }
152    }
153
154    /// Converter for channel send errors
155    pub fn from_channel_send_error(e: SendError<ScanMessage>) -> Self {
156        RLanLibError::NotifierSendError(SendError(Box::from(e.0)))
157    }
158}
159
160unsafe impl Send for RLanLibError {}
161unsafe impl Sync for RLanLibError {}
162
163/// Custom Result type for this library. All Errors exposed by this library
164/// will be returned as [`RLanLibError`]
165pub type Result<T> = std::result::Result<T, RLanLibError>;