mirror of
https://github.com/GyulyVGC/sniffnet.git
synced 2025-12-23 22:29:01 -05:00
draft icons for processes
This commit is contained in:
9
Cargo.lock
generated
9
Cargo.lock
generated
@@ -3679,6 +3679,14 @@ version = "0.5.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315"
|
checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "picon"
|
||||||
|
version = "0.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"objc2-app-kit 0.3.1",
|
||||||
|
"objc2-foundation 0.3.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project"
|
name = "pin-project"
|
||||||
version = "1.1.10"
|
version = "1.1.10"
|
||||||
@@ -4775,6 +4783,7 @@ dependencies = [
|
|||||||
"phf 0.12.1",
|
"phf 0.12.1",
|
||||||
"phf_codegen",
|
"phf_codegen",
|
||||||
"phf_shared 0.12.1",
|
"phf_shared 0.12.1",
|
||||||
|
"picon",
|
||||||
"plotters",
|
"plotters",
|
||||||
"plotters-iced",
|
"plotters-iced",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
|
|||||||
@@ -58,10 +58,7 @@ clap = { version = "4.5.41", features = ["derive"] }
|
|||||||
tokio = { version = "1.46.1", features = ["macros"] }
|
tokio = { version = "1.46.1", features = ["macros"] }
|
||||||
async-channel = "2.5.0"
|
async-channel = "2.5.0"
|
||||||
listeners = { path = "../listeners" }
|
listeners = { path = "../listeners" }
|
||||||
#cocoa = "0.24"
|
picon = { path = "../picon" }
|
||||||
#objc = "0.2"
|
|
||||||
#libc = "0.2.174"
|
|
||||||
#image = "0.24"
|
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
gag = "1.0.0"
|
gag = "1.0.0"
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
use crate::networking::types::data_info_host::DataInfoHost;
|
use crate::networking::types::data_info_host::DataInfoHost;
|
||||||
use crate::networking::types::filters::Filters;
|
use crate::networking::types::filters::Filters;
|
||||||
use crate::networking::types::host::Host;
|
use crate::networking::types::host::Host;
|
||||||
|
use crate::networking::types::process::Process;
|
||||||
use crate::report::get_report_entries::{
|
use crate::report::get_report_entries::{
|
||||||
get_host_entries, get_process_entries, get_service_entries,
|
get_host_entries, get_process_entries, get_service_entries,
|
||||||
};
|
};
|
||||||
@@ -423,6 +424,10 @@ fn col_process<'a>(sniffer: &Sniffer) -> Column<'a, Message, StyleType> {
|
|||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
for (process, data_info) in &entries {
|
for (process, data_info) in &entries {
|
||||||
|
let Process::Known(listener_process) = process else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
let content = simpler_bar(
|
let content = simpler_bar(
|
||||||
process.to_string(),
|
process.to_string(),
|
||||||
data_info,
|
data_info,
|
||||||
@@ -436,11 +441,13 @@ fn col_process<'a>(sniffer: &Sniffer) -> Column<'a, Message, StyleType> {
|
|||||||
Row::new()
|
Row::new()
|
||||||
.spacing(5)
|
.spacing(5)
|
||||||
.align_y(Vertical::Center)
|
.align_y(Vertical::Center)
|
||||||
// .push_maybe(
|
.push_maybe(
|
||||||
// handle
|
sniffer
|
||||||
// .clone()
|
.picons
|
||||||
// .map(|h| Image::new(h).height(FLAGS_HEIGHT_BIG)),
|
.get(&listener_process.path)
|
||||||
// )
|
.clone()
|
||||||
|
.map(|h| Image::new(h).height(FLAGS_HEIGHT_BIG)),
|
||||||
|
)
|
||||||
.push(content),
|
.push(content),
|
||||||
)
|
)
|
||||||
.padding(Padding::new(5.0).right(15).left(10))
|
.padding(Padding::new(5.0).right(15).left(10))
|
||||||
|
|||||||
@@ -60,7 +60,7 @@
|
|||||||
use iced::keyboard::key::Named;
|
use iced::keyboard::key::Named;
|
||||||
use iced::keyboard::{Event, Key, Modifiers};
|
use iced::keyboard::{Event, Key, Modifiers};
|
||||||
use iced::mouse::Event::ButtonPressed;
|
use iced::mouse::Event::ButtonPressed;
|
||||||
use iced::widget::Column;
|
use iced::widget::{Column, image};
|
||||||
use iced::window::{Id, Level};
|
use iced::window::{Id, Level};
|
||||||
use iced::{Element, Point, Size, Subscription, Task, window};
|
use iced::{Element, Point, Size, Subscription, Task, window};
|
||||||
use pcap::Device;
|
use pcap::Device;
|
||||||
@@ -149,6 +149,8 @@ pub struct Sniffer {
|
|||||||
pub listeners: HashMap<(u16, listeners::Protocol), listeners::Process>,
|
pub listeners: HashMap<(u16, listeners::Protocol), listeners::Process>,
|
||||||
/// Processes with their DataInfo
|
/// Processes with their DataInfo
|
||||||
pub processes: HashMap<Process, DataInfo>,
|
pub processes: HashMap<Process, DataInfo>,
|
||||||
|
/// Process icons
|
||||||
|
pub picons: HashMap<String, image::Handle>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sniffer {
|
impl Sniffer {
|
||||||
@@ -198,6 +200,7 @@ pub fn new(configs: Configs) -> Self {
|
|||||||
import_pcap_path: String::new(),
|
import_pcap_path: String::new(),
|
||||||
listeners: HashMap::new(),
|
listeners: HashMap::new(),
|
||||||
processes: HashMap::new(),
|
processes: HashMap::new(),
|
||||||
|
picons: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -712,7 +715,14 @@ fn fetch_listeners(&mut self) {
|
|||||||
for l in curr_listeners.into_iter().filter(|l| l.socket.port() != 0) {
|
for l in curr_listeners.into_iter().filter(|l| l.socket.port() != 0) {
|
||||||
let port = l.socket.port();
|
let port = l.socket.port();
|
||||||
let protocol = l.protocol;
|
let protocol = l.protocol;
|
||||||
|
let path = l.process.path.clone();
|
||||||
self.listeners.insert((port, protocol), l.process);
|
self.listeners.insert((port, protocol), l.process);
|
||||||
|
|
||||||
|
if !self.picons.contains_key(&path) {
|
||||||
|
let bytes = picon::get_icon_by_path(&path);
|
||||||
|
let handle = image::Handle::from_bytes(bytes.bytes);
|
||||||
|
self.picons.insert(path, handle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (k, v) in self
|
for (k, v) in self
|
||||||
|
|||||||
@@ -265,8 +265,6 @@ pub fn modify_or_insert_in_map(
|
|||||||
) -> (TrafficDirection, Service) {
|
) -> (TrafficDirection, Service) {
|
||||||
let mut traffic_direction = TrafficDirection::default();
|
let mut traffic_direction = TrafficDirection::default();
|
||||||
let mut service = Service::Unknown;
|
let mut service = Service::Unknown;
|
||||||
// let mut process = "?".to_string();
|
|
||||||
// let mut picon = None;
|
|
||||||
|
|
||||||
if !info_traffic_msg.map.contains_key(key) {
|
if !info_traffic_msg.map.contains_key(key) {
|
||||||
// first occurrence of key (in this time interval)
|
// first occurrence of key (in this time interval)
|
||||||
@@ -284,43 +282,6 @@ pub fn modify_or_insert_in_map(
|
|||||||
);
|
);
|
||||||
// determine upper layer service
|
// determine upper layer service
|
||||||
service = get_service(key, traffic_direction, my_interface_addresses);
|
service = get_service(key, traffic_direction, my_interface_addresses);
|
||||||
// determine process
|
|
||||||
// if let Some(local_port) = get_local_port(key, traffic_direction) {
|
|
||||||
// let processes = get_processes();
|
|
||||||
// let pid = processes.get(&local_port).unwrap_or(&0);
|
|
||||||
// let path = get_executable_path(*pid as i32);
|
|
||||||
// let mut image: Option<iced::widget::Image> = None;
|
|
||||||
// // println!("Process: {} (PID: {})", path, p.pid);
|
|
||||||
// if let Some(app_path) = path {
|
|
||||||
// process = Path::new(&app_path)
|
|
||||||
// .file_name()
|
|
||||||
// .unwrap_or_default()
|
|
||||||
// .to_string_lossy()
|
|
||||||
// .to_string();
|
|
||||||
// // println!("--> Exe path: {}", app_path);
|
|
||||||
// if let Some(bundle_path) = find_app_bundle_path(&app_path) {
|
|
||||||
// // println!("--> Bundle path: {}", bundle_path);
|
|
||||||
// if let Some(tiff) = get_icon_tiff_bytes(&bundle_path) {
|
|
||||||
// let img = image::load_from_memory(&tiff).expect("Failed to decode image");
|
|
||||||
// // resize the image
|
|
||||||
// let resized =
|
|
||||||
// img.resize_exact(64, 64, image::imageops::FilterType::Lanczos3);
|
|
||||||
// let (width, height) = resized.dimensions();
|
|
||||||
// // println!("--> Icon size: {}x{}", width, height);
|
|
||||||
// // crop the image
|
|
||||||
// let sub = image::imageops::crop_imm(&resized, 6, 6, 52, 52).to_image();
|
|
||||||
// let (width, height) = sub.dimensions();
|
|
||||||
// // println!("--> Cropped icon size: {}x{}", width, height);
|
|
||||||
//
|
|
||||||
// picon = Some(iced::widget::image::Handle::from_rgba(
|
|
||||||
// width,
|
|
||||||
// height,
|
|
||||||
// sub.into_raw(),
|
|
||||||
// ));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let timestamp = info_traffic_msg.last_packet_timestamp;
|
let timestamp = info_traffic_msg.last_packet_timestamp;
|
||||||
@@ -373,66 +334,6 @@ pub fn modify_or_insert_in_map(
|
|||||||
(new_info.traffic_direction, new_info.service)
|
(new_info.traffic_direction, new_info.service)
|
||||||
}
|
}
|
||||||
|
|
||||||
// unsafe extern "C" {
|
|
||||||
// fn proc_pidpath(pid: c_int, buffer: *mut libc::c_void, buffersize: u32) -> c_int;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn get_executable_path(pid: i32) -> Option<String> {
|
|
||||||
// let mut buf = vec![0u8; libc::PROC_PIDPATHINFO_MAXSIZE as usize];
|
|
||||||
// let ret = unsafe { proc_pidpath(pid, buf.as_mut_ptr() as *mut _, buf.len() as u32) };
|
|
||||||
//
|
|
||||||
// if ret > 0 {
|
|
||||||
// let path = CStr::from_bytes_until_nul(&buf).unwrap();
|
|
||||||
// Some(path.to_string_lossy().into_owned())
|
|
||||||
// } else {
|
|
||||||
// None
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
fn find_app_bundle_path(exe_path: &str) -> Option<String> {
|
|
||||||
let mut current = std::path::Path::new(exe_path);
|
|
||||||
let mut last_app_dir: Option<std::path::PathBuf> = None;
|
|
||||||
|
|
||||||
// Walk up the path, including the input
|
|
||||||
loop {
|
|
||||||
if let Some(file_name) = current.file_name() {
|
|
||||||
if file_name.to_string_lossy().ends_with(".app") {
|
|
||||||
last_app_dir = Some(current.to_path_buf());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match current.parent() {
|
|
||||||
Some(parent) => current = parent,
|
|
||||||
None => break,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
last_app_dir.map(|p| p.to_string_lossy().into_owned())
|
|
||||||
}
|
|
||||||
|
|
||||||
// fn get_icon_tiff_bytes(app_path: &str) -> Option<Vec<u8>> {
|
|
||||||
// unsafe {
|
|
||||||
// let ns_app_path: id = NSString::alloc(nil).init_str(app_path);
|
|
||||||
// let workspace: id = msg_send![class!(NSWorkspace), sharedWorkspace];
|
|
||||||
// let icon: id = msg_send![workspace, iconForFile: ns_app_path];
|
|
||||||
//
|
|
||||||
// if icon == nil {
|
|
||||||
// return None;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Get TIFF representation (NSData)
|
|
||||||
// let tiff_data: id = msg_send![icon, TIFFRepresentation];
|
|
||||||
// if tiff_data == nil {
|
|
||||||
// return None;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Convert NSData to Vec<u8>
|
|
||||||
// let length: usize = msg_send![tiff_data, length];
|
|
||||||
// let bytes: *const u8 = msg_send![tiff_data, bytes];
|
|
||||||
// Some(std::slice::from_raw_parts(bytes, length).to_vec())
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
/// Returns the traffic direction observed (incoming or outgoing)
|
/// Returns the traffic direction observed (incoming or outgoing)
|
||||||
fn get_traffic_direction(
|
fn get_traffic_direction(
|
||||||
source_ip: &IpAddr,
|
source_ip: &IpAddr,
|
||||||
|
|||||||
Reference in New Issue
Block a user