From b351a56077c2fae187b73cda188bdccf80433376 Mon Sep 17 00:00:00 2001 From: Zander Lewis Date: Sun, 20 Oct 2024 17:56:24 -0400 Subject: [PATCH] Speed up `netscanner` (#42) feat: refactoring of using .clone() everywhere --- src/components/discovery.rs | 148 ++++++++++++++++--------------- src/components/packetdump.rs | 7 +- src/components/sniff.rs | 22 ++--- src/components/tabs.rs | 14 ++- src/components/wifi_chart.rs | 5 +- src/components/wifi_interface.rs | 10 +-- src/components/wifi_scan.rs | 4 +- 7 files changed, 102 insertions(+), 108 deletions(-) diff --git a/src/components/discovery.rs b/src/components/discovery.rs index 108b54a..627f005 100644 --- a/src/components/discovery.rs +++ b/src/components/discovery.rs @@ -105,16 +105,17 @@ impl Discovery { } fn set_cidr(&mut self, cidr_str: String, scan: bool) { - match &cidr_str.parse::() { + match cidr_str.parse::() { Ok(ip_cidr) => { - self.cidr = Some(*ip_cidr); + self.cidr = Some(ip_cidr); if scan { self.scan(); } } Err(e) => { - let tx = self.action_tx.clone().unwrap(); - tx.send(Action::CidrError).unwrap(); + if let Some(tx) = &self.action_tx { + tx.send(Action::CidrError).unwrap(); + } } } } @@ -125,59 +126,61 @@ impl Discovery { } fn send_arp(&mut self, target_ip: Ipv4Addr) { - let active_interface = self.active_interface.clone().unwrap(); - if let Some(active_interface_mac) = active_interface.mac { - let ipv4 = active_interface.ips.iter().find(|f| f.is_ipv4()).unwrap(); - let source_ip: Ipv4Addr = ipv4.ip().to_string().parse().unwrap(); - - let (mut sender, _) = - match pnet::datalink::channel(&active_interface, Default::default()) { - Ok(Channel::Ethernet(tx, rx)) => (tx, rx), - Ok(_) => { - let tx_action = self.action_tx.clone().unwrap(); - tx_action - .send(Action::Error("Unknown or unsopported channel type".into())) - .unwrap(); - return; - } - Err(e) => { - let tx_action = self.action_tx.clone().unwrap(); - tx_action - .send(Action::Error(format!( - "Unable to create datalink channel: {e}" - ))) - .unwrap(); - return; - } - }; - - let mut ethernet_buffer = [0u8; 42]; - let mut ethernet_packet = MutableEthernetPacket::new(&mut ethernet_buffer).unwrap(); - - ethernet_packet.set_destination(MacAddr::broadcast()); - // ethernet_packet.set_source(active_interface.mac.unwrap()); - ethernet_packet.set_source(active_interface_mac); - ethernet_packet.set_ethertype(EtherTypes::Arp); - - let mut arp_buffer = [0u8; 28]; - let mut arp_packet = MutableArpPacket::new(&mut arp_buffer).unwrap(); - - arp_packet.set_hardware_type(ArpHardwareTypes::Ethernet); - arp_packet.set_protocol_type(EtherTypes::Ipv4); - arp_packet.set_hw_addr_len(6); - arp_packet.set_proto_addr_len(4); - arp_packet.set_operation(ArpOperations::Request); - arp_packet.set_sender_hw_addr(active_interface_mac); - arp_packet.set_sender_proto_addr(source_ip); - arp_packet.set_target_hw_addr(MacAddr::zero()); - arp_packet.set_target_proto_addr(target_ip); - - ethernet_packet.set_payload(arp_packet.packet_mut()); - - sender - .send_to(ethernet_packet.packet(), None) - .unwrap() - .unwrap(); + if let Some(active_interface) = &self.active_interface { + if let Some(active_interface_mac) = active_interface.mac { + let ipv4 = active_interface.ips.iter().find(|f| f.is_ipv4()).unwrap(); + let source_ip: Ipv4Addr = ipv4.ip().to_string().parse().unwrap(); + + let (mut sender, _) = + match pnet::datalink::channel(active_interface, Default::default()) { + Ok(Channel::Ethernet(tx, rx)) => (tx, rx), + Ok(_) => { + if let Some(tx_action) = &self.action_tx { + tx_action + .send(Action::Error("Unknown or unsupported channel type".into())) + .unwrap(); + } + return; + } + Err(e) => { + if let Some(tx_action) = &self.action_tx { + tx_action + .send(Action::Error(format!( + "Unable to create datalink channel: {e}" + ))) + .unwrap(); + } + return; + } + }; + + let mut ethernet_buffer = [0u8; 42]; + let mut ethernet_packet = MutableEthernetPacket::new(&mut ethernet_buffer).unwrap(); + + ethernet_packet.set_destination(MacAddr::broadcast()); + ethernet_packet.set_source(active_interface_mac); + ethernet_packet.set_ethertype(EtherTypes::Arp); + + let mut arp_buffer = [0u8; 28]; + let mut arp_packet = MutableArpPacket::new(&mut arp_buffer).unwrap(); + + arp_packet.set_hardware_type(ArpHardwareTypes::Ethernet); + arp_packet.set_protocol_type(EtherTypes::Ipv4); + arp_packet.set_hw_addr_len(6); + arp_packet.set_proto_addr_len(4); + arp_packet.set_operation(ArpOperations::Request); + arp_packet.set_sender_hw_addr(active_interface_mac); + arp_packet.set_sender_proto_addr(source_ip); + arp_packet.set_target_hw_addr(MacAddr::zero()); + arp_packet.set_target_proto_addr(target_ip); + + ethernet_packet.set_payload(arp_packet.packet_mut()); + + sender + .send_to(ethernet_packet.packet(), None) + .unwrap() + .unwrap(); + } } } @@ -186,10 +189,9 @@ impl Discovery { if let Some(cidr) = self.cidr { self.is_scanning = true; - let tx = self.action_tx.clone().unwrap(); + let tx = self.action_tx.as_ref().unwrap().clone(); self.task = tokio::spawn(async move { let ips = get_ips4_from_cidr(cidr); - let tx = tx.clone(); let chunks: Vec<_> = ips.chunks(POOL_SIZE).collect(); for chunk in chunks { let tasks: Vec<_> = chunk @@ -250,23 +252,23 @@ impl Discovery { } fn process_ip(&mut self, ip: &str) { - let tx = self.action_tx.clone().unwrap(); + let tx = self.action_tx.as_ref().unwrap(); let ipv4: Ipv4Addr = ip.parse().unwrap(); self.send_arp(ipv4); if let Some(n) = self.scanned_ips.iter_mut().find(|item| item.ip == ip) { let hip: IpAddr = ip.parse().unwrap(); - let host = lookup_addr(&hip).unwrap_or(String::from("")); + let host = lookup_addr(&hip).unwrap_or_default(); n.hostname = host; n.ip = ip.to_string(); } else { let hip: IpAddr = ip.parse().unwrap(); - let host = lookup_addr(&hip).unwrap_or(String::from("")); + let host = lookup_addr(&hip).unwrap_or_default(); self.scanned_ips.push(ScannedIp { ip: ip.to_string(), - mac: String::from(""), + mac: String::new(), hostname: host, - vendor: String::from(""), + vendor: String::new(), }); self.scanned_ips.sort_by(|a, b| { @@ -336,11 +338,11 @@ impl Discovery { self.scrollbar_state = self.scrollbar_state.position(index); } - fn make_table( - scanned_ips: Vec, + fn make_table<'a>( + scanned_ips: &'a Vec, cidr: Option, ip_num: i32, - ) -> Table<'static> { + ) -> Table<'a> { let header = Row::new(vec!["ip", "mac", "hostname", "vendor"]) .style(Style::default().fg(Color::Yellow)) .top_margin(1) @@ -358,9 +360,9 @@ impl Discovery { format!("{ip:<2}"), Style::default().fg(Color::Blue), )), - Cell::from(sip.mac.clone().green()), - Cell::from(sip.hostname.clone()), - Cell::from(sip.vendor.clone().yellow()), + Cell::from(sip.mac.as_str().green()), + Cell::from(sip.hostname.as_str()), + Cell::from(sip.vendor.as_str().yellow()), ])); } @@ -657,8 +659,8 @@ impl Component for Discovery { table_rect.y += 1; table_rect.height -= 1; - let table = Self::make_table(self.scanned_ips.clone(), self.cidr, self.ip_num); - f.render_stateful_widget(table, table_rect, &mut self.table_state.clone()); + let table = Self::make_table(&self.scanned_ips, self.cidr, self.ip_num); + f.render_stateful_widget(table, table_rect, &mut self.table_state); // -- SCROLLBAR let scrollbar = Self::make_scrollbar(); @@ -694,7 +696,7 @@ impl Component for Discovery { let scroll = self.input.visual_scroll(INPUT_SIZE - 3); let mut block = self.make_input(scroll); if self.is_scanning { - block = block.clone().add_modifier(Modifier::DIM); + block = block.add_modifier(Modifier::DIM); } f.render_widget(block, input_rect); diff --git a/src/components/packetdump.rs b/src/components/packetdump.rs index f64434a..ac36b4b 100644 --- a/src/components/packetdump.rs +++ b/src/components/packetdump.rs @@ -414,7 +414,7 @@ impl PacketDump { let (_, mut receiver) = match pnet::datalink::channel(&interface, Default::default()) { Ok(Channel::Ethernet(tx, rx)) => (tx, rx), Ok(_) => { - tx.send(Action::Error("Unknown or unsopported channel type".into())) + tx.send(Action::Error("Unknown or unsupported channel type".into())) .unwrap(); return; } @@ -424,10 +424,9 @@ impl PacketDump { ))) .unwrap(); return; - } // Ok(_) => panic!("Unknown channel type"), - // Err(e) => panic!("Error happened {}", e), + } }; - // while !paused.load(Ordering::Relaxed) { + loop { let mut buf: [u8; 1600] = [0u8; 1600]; let mut fake_ethernet_frame = MutableEthernetPacket::new(&mut buf[..]).unwrap(); diff --git a/src/components/sniff.rs b/src/components/sniff.rs index 73ddc49..eabb199 100644 --- a/src/components/sniff.rs +++ b/src/components/sniff.rs @@ -248,13 +248,13 @@ impl Sniffer { }, ); - let a_intfs = self.active_inft_ips.clone(); + let a_intfs = &self.active_inft_ips; let tu = self .traffic_ips .iter() .filter(|item| { let t_ip = item.ip.to_string(); - for i_ip in a_intfs.clone() { + for i_ip in a_intfs { if i_ip.ip().to_string() == t_ip { return false; } @@ -265,9 +265,9 @@ impl Sniffer { let mut tu_ip = String::from(""); let mut tu_name = String::from(""); - if tu.is_some() { - tu_ip = tu.unwrap().ip.to_string(); - tu_name = format!(" ({})", tu.unwrap().hostname); + if let Some(tu) = tu { + tu_ip = tu.ip.to_string(); + tu_name = format!(" ({})", tu.hostname); } let top_uploader = Line::from(vec![ "Top uploader: ".into(), @@ -289,7 +289,7 @@ impl Sniffer { .iter() .filter(|item| { let t_ip = item.ip.to_string(); - for i_ip in a_intfs.clone() { + for i_ip in a_intfs { if i_ip.ip().to_string() == t_ip { return false; } @@ -300,9 +300,9 @@ impl Sniffer { let mut td_ip = String::from(""); let mut td_name = String::from(""); - if td.is_some() { - td_ip = td.unwrap().ip.to_string(); - td_name = format!(" ({})", tu.unwrap().hostname); + if let Some(td) = td { + td_ip = td.ip.to_string(); + td_name = format!(" ({})", td.hostname); } let top_downloader = Line::from(vec![ "Top downloader: ".into(), @@ -357,8 +357,8 @@ impl Component for Sniffer { if let Action::PacketDump(time, packet, packet_type) = action { match packet_type { - PacketTypeEnum::Tcp => self.process_packet(packet.clone()), - PacketTypeEnum::Udp => self.process_packet(packet.clone()), + PacketTypeEnum::Tcp => self.process_packet(packet), + PacketTypeEnum::Udp => self.process_packet(packet), _ => {} } } diff --git a/src/components/tabs.rs b/src/components/tabs.rs index bfe163d..dd7e9f5 100644 --- a/src/components/tabs.rs +++ b/src/components/tabs.rs @@ -82,15 +82,11 @@ impl Tabs { } fn next_tab(&mut self) { - let mut new_tab_index = self.tab_index + 1; - new_tab_index %= TabsEnum::COUNT; - - let tab_enum: TabsEnum = TabsEnum::iter().nth(new_tab_index).unwrap(); - self.action_tx - .clone() - .unwrap() - .send(Action::TabChange(tab_enum)) - .unwrap(); + self.tab_index = (self.tab_index + 1) % TabsEnum::COUNT; + if let Some(ref action_tx) = self.action_tx { + let tab_enum = TabsEnum::iter().nth(self.tab_index).unwrap(); + action_tx.send(Action::TabChange(tab_enum)).unwrap(); + } } } diff --git a/src/components/wifi_chart.rs b/src/components/wifi_chart.rs index c168e42..cbac4db 100644 --- a/src/components/wifi_chart.rs +++ b/src/components/wifi_chart.rs @@ -53,7 +53,7 @@ impl WifiChart { Ok(()) } - fn parse_char_data(&mut self, nets: &Vec) { + fn parse_char_data(&mut self, nets: &[WifiInfo]) { for w in nets { let seconds: f64 = w.time.second() as f64; if let Some(p) = self @@ -67,7 +67,6 @@ impl WifiChart { } else { self.wifi_datasets.push(WifiDataset { ssid: w.ssid.clone(), - // data: vec![(0.0, 0.0)], data: MaxSizeVec::new(100), color: w.color, }); @@ -82,7 +81,7 @@ impl WifiChart { for d in &self.wifi_datasets { let d_data = &d.data.get_vec(); let dataset = Dataset::default() - .name(d.ssid.clone()) + .name(&*d.ssid) .marker(symbols::Marker::Dot) .style(Style::default().fg(d.color)) .graph_type(GraphType::Line) diff --git a/src/components/wifi_interface.rs b/src/components/wifi_interface.rs index 7245dd6..6b19adb 100644 --- a/src/components/wifi_interface.rs +++ b/src/components/wifi_interface.rs @@ -135,20 +135,18 @@ impl WifiInterface { if let Some(wifi_info) = &self.wifi_info { let interface = &wifi_info.interface; let interface_label = "Interface:"; - let ssid = &wifi_info.ssid.clone(); + let ssid = &wifi_info.ssid; let ssid_label = "SSID:"; let ifindex = &wifi_info.ifindex; let ifindex_label = "Intf index:"; - let channel = &wifi_info.channel.clone(); + let channel = &wifi_info.channel; let channel_label = "Channel:"; - let txpower = &wifi_info.txpower.clone(); + let txpower = &wifi_info.txpower; let txpower_label = "TxPower:"; - let mac = &wifi_info.mac.clone(); + let mac = &wifi_info.mac; let mac_label = "Mac addr:"; - // let list = List::new() let mut items: Vec = Vec::new(); - // let list = List::new(items); items.push(ListItem::new(vec![ Line::from(vec![ diff --git a/src/components/wifi_scan.rs b/src/components/wifi_scan.rs index 8c59c71..1b890f8 100644 --- a/src/components/wifi_scan.rs +++ b/src/components/wifi_scan.rs @@ -185,10 +185,10 @@ impl WifiScan { } else { wifi_nets.push(WifiInfo { time: now, - ssid: w.ssid.clone(), + ssid: w.ssid, channel: w.channel.parse::().unwrap_or(0), signal: w.signal_level.parse::().unwrap_or(-100.00), - mac: w.mac.clone(), + mac: w.mac, color: COLORS_NAMES[wifi_nets.len() % COLORS_NAMES.len()], }); }