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 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 wire::{Reader, Sender},
24};
25
26#[derive(Error, Debug)]
28pub enum RLanLibError {
29 #[error("wire error: {_0}")]
31 Wire(String),
32
33 #[error("failed to send notification message: {:#?}", _0)]
35 NotifierSendError(#[from] SendError<Box<ScanMessage>>),
36
37 #[error("failed to get lock on packet reader: {_0}")]
39 PacketReaderLock(String),
40
41 #[error("failed to get lock on packet sender: {_0}")]
43 PacketSenderLock(String),
44
45 #[error("thread error: {_0}")]
47 ThreadError(String),
48
49 #[error("failed to receive message from channel: {:#?}", _0)]
51 ChannelReceive(#[from] RecvError),
52
53 #[error("failed to build ARP packet: {_0}")]
55 ArpPacketBuild(#[from] ArpPacketBuilderError),
56
57 #[error("failed to build arp scanner: {_0}")]
59 ArpScannerBuild(#[from] ARPScannerBuilderError),
60
61 #[error("failed to build syn scanner: {_0}")]
63 SynScannerBuild(#[from] SYNScannerBuilderError),
64
65 #[error("failed to build heartbeat: {_0}")]
67 HeartBeatBuild(#[from] HeartBeatBuilderError),
68
69 #[error("failed to build RST packet: {_0}")]
71 RstPacketBuild(#[from] RstPacketBuilderError),
72
73 #[error("failed to build SYN packet: {_0}")]
75 SynPacketBuild(#[from] SynPacketBuilderError),
76
77 #[error("failed to build heartbeat packet: {_0}")]
79 HeartbeatPacketBuild(#[from] HeartbeatPacketBuilderError),
80
81 #[error("network interface error: {_0}")]
83 NetworkInterface(String),
84
85 #[error("scanning error: {error} - ip: {:#?}, port: {:#?}", ip, port)]
87 Scan {
88 error: String,
90 ip: Option<String>,
92 port: Option<String>,
94 },
95}
96
97impl From<Box<dyn Any + Send>> for RLanLibError {
98 fn from(value: Box<dyn Any + Send>) -> Self {
99 if let Some(s) = value.downcast_ref::<&'static str>() {
100 Self::ThreadError(format!("Thread panicked with: {}", s))
101 } else if let Some(s) = value.downcast_ref::<String>() {
102 Self::ThreadError(format!("Thread panicked with: {}", s))
103 } else {
104 Self::ThreadError("Thread panicked with an unknown type".into())
105 }
106 }
107}
108
109impl<'a> From<PoisonError<MutexGuard<'a, dyn Reader + 'static>>>
110 for RLanLibError
111{
112 fn from(value: PoisonError<MutexGuard<'a, dyn Reader + 'static>>) -> Self {
113 Self::PacketReaderLock(value.to_string())
114 }
115}
116
117impl<'a> From<PoisonError<MutexGuard<'a, dyn Sender + 'static>>>
118 for RLanLibError
119{
120 fn from(value: PoisonError<MutexGuard<'a, dyn Sender + 'static>>) -> Self {
121 Self::PacketSenderLock(value.to_string())
122 }
123}
124
125impl RLanLibError {
126 pub fn from_net_addr_parse_error(
128 ip: &str,
129 error: std::net::AddrParseError,
130 ) -> Self {
131 Self::Scan {
132 error: error.to_string(),
133 ip: Some(ip.to_string()),
134 port: None,
135 }
136 }
137
138 pub fn from_ipnet_addr_parse_error(
140 ip: &str,
141 error: ipnet::AddrParseError,
142 ) -> Self {
143 Self::Scan {
144 error: error.to_string(),
145 ip: Some(ip.to_string()),
146 port: None,
147 }
148 }
149
150 pub fn from_port_parse_int_err(port: &str, error: ParseIntError) -> Self {
152 Self::Scan {
153 error: error.to_string(),
154 ip: None,
155 port: Some(port.to_string()),
156 }
157 }
158
159 pub fn from_channel_send_error(e: SendError<ScanMessage>) -> Self {
161 RLanLibError::NotifierSendError(SendError(Box::from(e.0)))
162 }
163}
164
165unsafe impl Send for RLanLibError {}
166unsafe impl Sync for RLanLibError {}
167
168pub type Result<T> = std::result::Result<T, RLanLibError>;