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

Begin to show info on selected device view #23

Merged
merged 1 commit into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 8 additions & 14 deletions r-lanui/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,12 @@ pub const DEFAULT_CONFIG_ID: &str = "default";
pub const DEFAULT_PORTS_STR: &str = "22,80,443,2000-9999";
pub const DEFAULT_PORTS: [&str; 4] = ["22", "80", "443", "2000-9999"];

#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
pub enum SshID {
Ip(String),
Mac(String),
}

#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
pub struct SshOverride {
pub id: SshID,
pub port: u16,
pub identity_file: String,
pub user: String,
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct DeviceConfig {
pub id: String,
pub ssh_port: u16,
pub ssh_identity_file: String,
pub ssh_user: String,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
Expand All @@ -28,7 +22,7 @@ pub struct Config {
pub cidr: String,
pub theme: String,
pub ports: Vec<String>,
pub ssh_overrides: HashMap<SshID, SshOverride>,
pub device_configs: HashMap<String, DeviceConfig>,
}

pub fn get_default_ports() -> Vec<String> {
Expand All @@ -45,7 +39,7 @@ impl Config {
theme: Theme::Blue.to_string(),
cidr: "unknown".to_string(),
ports: get_default_ports(),
ssh_overrides: HashMap::new(),
device_configs: HashMap::new(),
}
}
}
Expand Down
42 changes: 16 additions & 26 deletions r-lanui/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ use simplelog;
use std::{
collections::{HashMap, HashSet},
env, fs,
net::Ipv4Addr,
str::FromStr,
sync::{
mpsc::{self, Receiver, Sender},
Arc, Mutex,
Expand Down Expand Up @@ -78,6 +76,7 @@ fn process_arp(
cidr: String,
rx: Receiver<ScanMessage>,
tx: Sender<ScanMessage>,
dispatcher: Arc<Dispatcher>,
) -> Result<(Vec<Device>, Receiver<ScanMessage>), ScanError> {
let mut arp_results: HashSet<Device> = HashSet::new();

Expand All @@ -102,13 +101,19 @@ fn process_arp(
if let Some(m) = msg.arp_message() {
debug!("received scanning message: {:?}", msg);
arp_results.insert(m.to_owned());
dispatcher.dispatch(Action::AddDevice(&DeviceWithPorts {
hostname: m.hostname.clone(),
ip: m.ip.clone(),
mac: m.mac.clone(),
open_ports: HashSet::new(),
vendor: m.vendor.clone(),
}));
}
}

handle.join().unwrap()?;

let mut items: Vec<Device> = arp_results.into_iter().collect();
items.sort_by_key(|i| Ipv4Addr::from_str(&i.ip.to_owned()).unwrap());
let items: Vec<Device> = arp_results.into_iter().collect();

Ok((items, rx))
}
Expand All @@ -122,6 +127,7 @@ fn process_syn(
rx: Receiver<ScanMessage>,
tx: Sender<ScanMessage>,
source_port: u16,
dispatcher: Arc<Dispatcher>,
) -> Result<Vec<DeviceWithPorts>, ScanError> {
let mut syn_results: Vec<DeviceWithPorts> = Vec::new();

Expand Down Expand Up @@ -160,6 +166,7 @@ fn process_syn(
match device {
Some(d) => {
d.open_ports.insert(m.open_port.to_owned());
dispatcher.dispatch(Action::AddDevice(d));
}
None => {
warn!("received syn result for unknown device: {:?}", m);
Expand All @@ -179,7 +186,6 @@ fn monitor_network(
config: Arc<Config>,
interface: Arc<NetworkInterface>,
dispatcher: Arc<Dispatcher>,
first_run: bool,
) -> JoinHandle<Result<(), ScanError>> {
info!("starting network monitor");
thread::spawn(move || -> Result<(), ScanError> {
Expand Down Expand Up @@ -216,25 +222,9 @@ fn monitor_network(
interface.cidr.clone(),
rx,
tx.clone(),
Arc::clone(&dispatcher),
)?;

if first_run {
// update view on first run to make results appear faster
// we'll fill in ports once syn scanning finishes
let with_ports = arp_results
.iter()
.map(|d| DeviceWithPorts {
hostname: d.hostname.clone(),
ip: d.ip.clone(),
mac: d.mac.clone(),
vendor: d.vendor.clone(),
open_ports: HashSet::new(),
})
.collect::<Vec<DeviceWithPorts>>();

dispatcher.dispatch(Action::UpdateDevices(&with_ports));
}

let results = process_syn(
Arc::clone(&packet_reader),
Arc::clone(&packet_sender),
Expand All @@ -244,14 +234,15 @@ fn monitor_network(
rx,
tx.clone(),
source_port,
Arc::clone(&dispatcher),
)?;

dispatcher.dispatch(Action::UpdateDevices(&results));
dispatcher.dispatch(Action::UpdateAllDevices(&results));

info!("network scan completed");

thread::sleep(time::Duration::from_secs(15));
let handle = monitor_network(config, interface, dispatcher, false);
let handle = monitor_network(config, interface, dispatcher);
handle.join().unwrap()
})
}
Expand All @@ -274,7 +265,7 @@ fn init(args: &Args, interface: &NetworkInterface) -> (Config, Arc<Dispatcher>)
config = Config {
id: fakeit::animal::animal().to_lowercase(),
cidr: interface.cidr.clone(),
ssh_overrides: HashMap::new(),
device_configs: HashMap::new(),
ports: args.ports.clone(),
theme: Theme::Blue.to_string(),
};
Expand Down Expand Up @@ -311,7 +302,6 @@ fn main() -> Result<(), Report> {
Arc::new(config),
Arc::new(interface),
Arc::clone(&dispatcher),
true,
);

if args.debug {
Expand Down
2 changes: 1 addition & 1 deletion r-lanui/src/ui/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use ratatui::{layout::Rect, Frame};

use super::store::store::Colors;

pub mod field;
pub mod footer;
pub mod input;
pub mod scrollbar;
pub mod table;

Expand Down
26 changes: 26 additions & 0 deletions r-lanui/src/ui/components/field.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use ratatui::{layout::Rect, style::Style, text::Line, widgets::Paragraph};

use crate::ui::store::store::Colors;

use super::Component;

pub struct Field {
pub name: String,
pub value: String,
}

impl Field {
pub fn new(name: String, value: String) -> Self {
Self { name, value }
}
}

impl Component for Field {
fn render(&mut self, f: &mut ratatui::Frame, area: Rect, colors: &Colors) {
let field = Paragraph::new(Line::from(format!("{0}: {1}", self.name, self.value)))
.style(Style::new().fg(colors.row_fg).bg(colors.buffer_bg))
.left_aligned();

f.render_widget(field, area);
}
}
11 changes: 0 additions & 11 deletions r-lanui/src/ui/components/input.rs

This file was deleted.

7 changes: 4 additions & 3 deletions r-lanui/src/ui/store/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ use crate::config::Config;
use super::types::{Theme, ViewName};

#[derive(Debug)]
pub enum Action<'view, 'conf_id, 'theme, 'devices, 'selected, 'config> {
pub enum Action<'view, 'conf_id, 'theme, 'devices, 'device, 'selected, 'config> {
UpdateView(&'view ViewName),
UpdateTheme((&'conf_id String, &'theme Theme)),
UpdateDevices(&'devices Vec<DeviceWithPorts>),
UpdateSelectedDevice(&'selected usize),
UpdateAllDevices(&'devices Vec<DeviceWithPorts>),
AddDevice(&'device DeviceWithPorts),
UpdateSelectedDevice(&'selected String),
SetConfig(&'conf_id String),
CreateAndSetConfig(&'config Config),
}
54 changes: 49 additions & 5 deletions r-lanui/src/ui/store/store.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
use std::sync::{Arc, Mutex};
use std::{
collections::HashMap,
net::Ipv4Addr,
str::FromStr,
sync::{Arc, Mutex},
};

use itertools::Itertools;
use r_lanlib::scanners::DeviceWithPorts;
use ratatui::style::{palette::tailwind, Color};

Expand Down Expand Up @@ -42,7 +48,8 @@ pub struct State {
pub view: ViewName,
pub config: Config,
pub devices: Vec<DeviceWithPorts>,
pub selected_device: usize,
pub device_map: HashMap<String, DeviceWithPorts>,
pub selected_device: Option<String>,
pub colors: Colors,
}

Expand All @@ -68,7 +75,8 @@ impl Store {
view: ViewName::Devices,
config,
devices: Vec::new(),
selected_device: 0,
device_map: HashMap::new(),
selected_device: None,
colors,
},
}
Expand All @@ -93,10 +101,46 @@ impl Store {
state.colors = Colors::new(theme.to_palette());
state
}
Action::UpdateDevices(devices) => {
Action::UpdateAllDevices(devices) => {
let mut state = self.state.clone();
let mut new_map: HashMap<String, DeviceWithPorts> = HashMap::new();
for d in devices {
new_map.insert(d.mac.clone(), d.clone());
}
state.devices = devices.clone();
state
.devices
.sort_by_key(|i| Ipv4Addr::from_str(&i.ip.to_owned()).unwrap());
state.device_map = new_map;
state
}
Action::AddDevice(device) => {
let mut state = self.state.clone();
if state.device_map.contains_key(&device.mac.clone()) {
let found_device = state
.devices
.iter_mut()
.find(|d| d.mac == device.mac)
.unwrap();
found_device.hostname = device.hostname.clone();
found_device.ip = device.ip.clone();
found_device.mac = device.mac.clone();

for p in &device.open_ports {
found_device.open_ports.insert(p.clone());
}

found_device.open_ports.iter().sorted_by_key(|p| p.id);
let mapped_device = state.device_map.get_mut(&device.mac.clone()).unwrap();
*mapped_device = found_device.clone();
} else {
state.devices.push(device.clone());
state.device_map.insert(device.mac.clone(), device.clone());
}
state
.devices
.sort_by_key(|i| Ipv4Addr::from_str(&i.ip.to_owned()).unwrap());
state
}
Action::SetConfig(config_id) => {
let mut state = self.state.clone();
Expand All @@ -118,7 +162,7 @@ impl Store {
}
Action::UpdateSelectedDevice(i) => {
let mut state = self.state.clone();
state.selected_device = *i;
state.selected_device = Some(i.clone());
state
}
};
Expand Down
Loading