From aa89be9971931e49cb4949e6497b657a211b6ac7 Mon Sep 17 00:00:00 2001 From: GyulyVGC Date: Sat, 21 Feb 2026 14:23:44 +0100 Subject: [PATCH] associate unassigned recent connections on port with the looked up program --- src/gui/sniffer.rs | 24 +++++++++++++++-- src/networking/manage_packets.rs | 3 +++ .../types/info_address_port_pair.rs | 26 ++++++++++++++++++- src/networking/types/program.rs | 4 +++ src/networking/types/program_lookup.rs | 2 +- 5 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/gui/sniffer.rs b/src/gui/sniffer.rs index 7ea707e3..4aa92afd 100644 --- a/src/gui/sniffer.rs +++ b/src/gui/sniffer.rs @@ -28,6 +28,7 @@ use crate::gui::types::timing_events::TimingEvents; use crate::mmdb::asn::ASN_MMDB; use crate::mmdb::country::COUNTRY_MMDB; use crate::mmdb::types::mmdb_reader::{MmdbReader, MmdbReaders}; +use crate::networking::manage_packets::get_local_port; use crate::networking::parse_packets::BackendTrafficMessage; use crate::networking::parse_packets::parse_packets; use crate::networking::traffic_preview::{TrafficPreview, traffic_preview}; @@ -40,7 +41,10 @@ use crate::networking::types::host::{Host, HostMessage}; use crate::networking::types::info_traffic::InfoTraffic; use crate::networking::types::ip_blacklist::IpBlacklist; use crate::networking::types::my_device::MyDevice; -use crate::networking::types::program_lookup::{ProgramLookup, lookup_program}; +use crate::networking::types::program::Program; +use crate::networking::types::program_lookup::{ + ProgramLookup, VALID_PROGRAM_TIMEOUT, lookup_program, +}; use crate::notifications::notify_and_log::notify_and_log; use crate::notifications::types::logged_notification::LoggedNotifications; use crate::notifications::types::notifications::{DataNotification, Notification}; @@ -872,9 +876,25 @@ impl Sniffer { self.combobox_data_states .data .update_program(lookup_res.2.as_ref()); + + // associate unassigned recent connections on port with the program + if lookup_res.2.is_some() { + self.info_traffic + .map + .iter_mut() + .filter(|(k, v)| { + v.program.is_unknown() + && v.final_instant.elapsed().as_millis() < VALID_PROGRAM_TIMEOUT + && get_local_port(k, v.traffic_direction) + == Some((lookup_res.0, lookup_res.1)) + }) + .for_each(|(_, v)| { + v.program = Program::from_proc(lookup_res.2.clone()); + }); + } + // update program lookup state with the new lookup result program_lookup.update(lookup_res); - // TODO: associate past unassigned connections on port with the program } } diff --git a/src/networking/manage_packets.rs b/src/networking/manage_packets.rs index 59f3bd7c..1449455f 100644 --- a/src/networking/manage_packets.rs +++ b/src/networking/manage_packets.rs @@ -21,6 +21,7 @@ use crate::networking::types::service_query::ServiceQuery; use crate::networking::types::traffic_direction::TrafficDirection; use crate::networking::types::traffic_type::TrafficType; use std::fmt::Write; +use std::time::Instant; include!(concat!(env!("OUT_DIR"), "/services.rs")); @@ -299,6 +300,7 @@ pub fn modify_or_insert_in_map( info.transmitted_bytes += exchanged_bytes; info.transmitted_packets += 1; info.final_timestamp = timestamp; + info.final_instant = Instant::now(); if key.protocol.eq(&Protocol::ICMP) { info.icmp_types .entry(icmp_type) @@ -319,6 +321,7 @@ pub fn modify_or_insert_in_map( transmitted_packets: 1, initial_timestamp: timestamp, final_timestamp: timestamp, + final_instant: Instant::now(), service, traffic_direction, icmp_types: if key.protocol.eq(&Protocol::ICMP) { diff --git a/src/networking/types/info_address_port_pair.rs b/src/networking/types/info_address_port_pair.rs index 47eed547..1c2cff5d 100644 --- a/src/networking/types/info_address_port_pair.rs +++ b/src/networking/types/info_address_port_pair.rs @@ -12,11 +12,12 @@ use crate::report::types::sort_type::SortType; use crate::utils::types::timestamp::Timestamp; use std::cmp::Ordering; use std::collections::HashMap; +use std::time::Instant; /// Struct useful to format the output report file and to keep track of statistics about the sniffed traffic. /// /// Each `InfoAddressPortPair` struct is associated to a single address:port pair. -#[derive(Clone, Default, Debug)] +#[derive(Clone, Debug)] pub struct InfoAddressPortPair { /// Source MAC address pub mac_address1: Option, @@ -30,6 +31,8 @@ pub struct InfoAddressPortPair { pub initial_timestamp: Timestamp, /// Last occurrence of information exchange featuring the associate address:port pair as a source or destination. pub final_timestamp: Timestamp, + /// Final instance of information exchange featuring the associate address:port pair as a source or destination (used for Program). + pub final_instant: Instant, /// Upper layer service carried by the associated address:port pair. pub service: Service, /// Determines if the connection is incoming or outgoing @@ -50,6 +53,7 @@ impl InfoAddressPortPair { self.transmitted_bytes += other.transmitted_bytes; self.transmitted_packets += other.transmitted_packets; self.final_timestamp = other.final_timestamp; + self.final_instant = other.final_instant; self.service = other.service; self.is_blacklisted = other.is_blacklisted; self.traffic_direction = other.traffic_direction; @@ -98,6 +102,26 @@ impl InfoAddressPortPair { } } +impl Default for InfoAddressPortPair { + fn default() -> Self { + Self { + mac_address1: None, + mac_address2: None, + transmitted_bytes: 0, + transmitted_packets: 0, + initial_timestamp: Timestamp::default(), + final_timestamp: Timestamp::default(), + final_instant: Instant::now(), + service: Service::default(), + traffic_direction: TrafficDirection::default(), + icmp_types: HashMap::new(), + arp_types: HashMap::new(), + is_blacklisted: false, + program: Program::default(), + } + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/networking/types/program.rs b/src/networking/types/program.rs index f651ed3c..ff54b4f3 100644 --- a/src/networking/types/program.rs +++ b/src/networking/types/program.rs @@ -24,6 +24,10 @@ impl Program { matches!(self, Program::Name(_)) } + pub fn is_unknown(&self) -> bool { + matches!(self, Program::Unknown) + } + pub fn from_proc(proc: Option) -> Self { proc.map_or(Program::Unknown, |proc| Program::Name(proc.name)) } diff --git a/src/networking/types/program_lookup.rs b/src/networking/types/program_lookup.rs index e5811061..ece3aecf 100644 --- a/src/networking/types/program_lookup.rs +++ b/src/networking/types/program_lookup.rs @@ -4,7 +4,7 @@ use std::collections::HashMap; use std::time::Instant; const RETRY_TIMEOUT: u128 = 1500; // milliseconds -const VALID_PROGRAM_TIMEOUT: u128 = 60_000; // milliseconds +pub const VALID_PROGRAM_TIMEOUT: u128 = 60_000; // milliseconds pub struct ProgramLookup { map: HashMap<(u16, Protocol), LookedUpProgram>,