1use 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#[derive(Error, Debug)]
27pub enum RLanLibError {
28 #[error("wire error: {_0}")]
30 Wire(String),
31
32 #[error("failed to send notification message: {:#?}", _0)]
34 NotifierSendError(#[from] SendError<Box<ScanMessage>>),
35
36 #[error("failed to get lock on packet reader: {_0}")]
38 PacketReaderLock(String),
39
40 #[error("failed to get lock on packet sender: {_0}")]
42 PacketSenderLock(String),
43
44 #[error("thread error: {_0}")]
46 ThreadError(String),
47
48 #[error("failed to receive message from channel: {:#?}", _0)]
50 ChannelReceive(#[from] RecvError),
51
52 #[error("failed to build ARP packet: {_0}")]
54 ArpPacketBuild(#[from] ArpPacketBuilderError),
55
56 #[error("failed to build arp scanner: {_0}")]
58 ArpScannerBuild(#[from] ARPScannerBuilderError),
59
60 #[error("failed to build syn scanner: {_0}")]
62 SynScannerBuild(#[from] SYNScannerBuilderError),
63
64 #[error("failed to build heartbeat: {_0}")]
66 HeartBeatBuild(#[from] HeartBeatBuilderError),
67
68 #[error("failed to build RST packet: {_0}")]
70 RstPacketBuild(#[from] RstPacketBuilderError),
71
72 #[error("failed to build SYN packet: {_0}")]
74 SynPacketBuild(#[from] SynPacketBuilderError),
75
76 #[error("failed to build heartbeat packet: {_0}")]
78 HeartbeatPacketBuild(#[from] HeartbeatPacketBuilderError),
79
80 #[error("scanning error: {error} - ip: {:#?}, port: {:#?}", ip, port)]
82 Scan {
83 error: String,
85 ip: Option<String>,
87 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 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 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 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 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
163pub type Result<T> = std::result::Result<T, RLanLibError>;