Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Speed up netscanner #42

Merged
merged 11 commits into from
Oct 20, 2024
148 changes: 75 additions & 73 deletions src/components/discovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,16 +105,17 @@ impl Discovery {
}

fn set_cidr(&mut self, cidr_str: String, scan: bool) {
match &cidr_str.parse::<Ipv4Cidr>() {
match cidr_str.parse::<Ipv4Cidr>() {
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 {
Chleba marked this conversation as resolved.
Show resolved Hide resolved
tx.send(Action::CidrError).unwrap();
}
}
}
}
Expand All @@ -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();
}
}
}

Expand All @@ -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
Expand Down Expand Up @@ -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| {
Expand Down Expand Up @@ -336,11 +338,11 @@ impl Discovery {
self.scrollbar_state = self.scrollbar_state.position(index);
}

fn make_table(
scanned_ips: Vec<ScannedIp>,
fn make_table<'a>(
scanned_ips: &'a Vec<ScannedIp>,
cidr: Option<Ipv4Cidr>,
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)
Expand All @@ -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()),
]));
}

Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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);

Expand Down
7 changes: 3 additions & 4 deletions src/components/packetdump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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();
Expand Down
22 changes: 11 additions & 11 deletions src/components/sniff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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 {
Chleba marked this conversation as resolved.
Show resolved Hide resolved
tu_ip = tu.ip.to_string();
tu_name = format!(" ({})", tu.hostname);
}
let top_uploader = Line::from(vec![
"Top uploader: ".into(),
Expand All @@ -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;
}
Expand All @@ -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 {
Chleba marked this conversation as resolved.
Show resolved Hide resolved
td_ip = td.ip.to_string();
td_name = format!(" ({})", td.hostname);
}
let top_downloader = Line::from(vec![
"Top downloader: ".into(),
Expand Down Expand Up @@ -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),
_ => {}
}
}
Expand Down
14 changes: 5 additions & 9 deletions src/components/tabs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}
}

Expand Down
5 changes: 2 additions & 3 deletions src/components/wifi_chart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl WifiChart {
Ok(())
}

fn parse_char_data(&mut self, nets: &Vec<WifiInfo>) {
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
Expand All @@ -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,
});
Expand All @@ -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)
Expand Down
10 changes: 4 additions & 6 deletions src/components/wifi_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<ListItem> = Vec::new();
// let list = List::new(items);

items.push(ListItem::new(vec![
Line::from(vec![
Expand Down
4 changes: 2 additions & 2 deletions src/components/wifi_scan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,10 +185,10 @@ impl WifiScan {
} else {
wifi_nets.push(WifiInfo {
time: now,
ssid: w.ssid.clone(),
ssid: w.ssid,
channel: w.channel.parse::<u8>().unwrap_or(0),
signal: w.signal_level.parse::<f32>().unwrap_or(-100.00),
mac: w.mac.clone(),
mac: w.mac,
color: COLORS_NAMES[wifi_nets.len() % COLORS_NAMES.len()],
});
}
Expand Down
Loading