diff --git a/build.rs b/build.rs index c205afab..2b94d460 100644 --- a/build.rs +++ b/build.rs @@ -64,10 +64,11 @@ fn build_services_phf() { fn get_valid_service_fmt_const(s: &str) -> String { match s.trim() { invalid - if ["", "unknown", "?", "-"].contains(&invalid) + if ["", "unknown", "-"].contains(&invalid) || !invalid.is_ascii() || invalid.starts_with('#') - || invalid.contains(' ') => + || invalid.contains(' ') + || invalid.contains('?') => { panic!("Invalid service name found: {invalid}") } diff --git a/src/gui/pages/overview_page.rs b/src/gui/pages/overview_page.rs index 9e026262..a8ec3f58 100644 --- a/src/gui/pages/overview_page.rs +++ b/src/gui/pages/overview_page.rs @@ -425,7 +425,7 @@ fn col_service(width: f32, sniffer: &Sniffer) -> Column<'static, Message, Render button(content) .padding([5, 15, 8, 10]) .on_press(Message::Search(SearchParameters { - service: service.to_string(), + service: service.to_string_with_equal_prefix(), ..SearchParameters::default() })) .style(ButtonType::Neutral), diff --git a/src/networking/manage_packets.rs b/src/networking/manage_packets.rs index a47bb5c0..ace0503f 100644 --- a/src/networking/manage_packets.rs +++ b/src/networking/manage_packets.rs @@ -1324,10 +1324,11 @@ fn test_all_services_map_key_and_values_are_valid() { }; // name is valid... assert!( - !["", "unknown", "?", "-"].contains(&name) + !["", "unknown", "-"].contains(&name) && name.is_ascii() && !name.starts_with('#') && !name.contains(' ') + && !name.contains('?') ); // just to count and verify number of distinct services distinct_services.insert(name.to_string()); diff --git a/src/networking/types/info_address_port_pair.rs b/src/networking/types/info_address_port_pair.rs index 3277b8e3..44e8febf 100644 --- a/src/networking/types/info_address_port_pair.rs +++ b/src/networking/types/info_address_port_pair.rs @@ -26,7 +26,7 @@ pub struct InfoAddressPortPair { pub initial_timestamp: DateTime, /// Last occurrence of information exchange featuring the associate address:port pair as a source or destination. pub final_timestamp: DateTime, - /// Application layer protocol carried by the associated address:port pair. + /// Upper layer service carried by the associated address:port pair. pub service: Service, /// Determines if the connection is incoming or outgoing pub traffic_direction: TrafficDirection, diff --git a/src/networking/types/info_traffic.rs b/src/networking/types/info_traffic.rs index 2ddfe4a6..7f84f30b 100644 --- a/src/networking/types/info_traffic.rs +++ b/src/networking/types/info_traffic.rs @@ -33,7 +33,7 @@ pub struct InfoTraffic { pub favorite_hosts: HashSet, /// Collection of favorite hosts that exchanged data in the last interval pub favorites_last_interval: HashSet, - /// Map of the application layer protocols with their data info + /// Map of the upper layer services with their data info pub services: HashMap, /// Map of the addresses waiting for a rDNS resolution; used to NOT send multiple rDNS for the same address pub addresses_waiting_resolution: HashMap, diff --git a/src/networking/types/service.rs b/src/networking/types/service.rs index 60ace30d..b6817412 100644 --- a/src/networking/types/service.rs +++ b/src/networking/types/service.rs @@ -10,6 +10,15 @@ pub enum Service { NotApplicable, } +impl Service { + pub fn to_string_with_equal_prefix(&self) -> String { + match self { + Service::Name(_) | Service::NotApplicable => ["=", &self.to_string()].concat(), + Service::Unknown => self.to_string(), + } + } +} + impl std::fmt::Display for Service { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { @@ -26,19 +35,26 @@ mod tests { #[test] fn test_service_display_unknown() { - let test_str = Service::Unknown.to_string(); - assert_eq!(test_str, "?"); + assert_eq!(Service::Unknown.to_string(), "?"); } #[test] fn test_service_display_not_applicable() { - let test_str = Service::NotApplicable.to_string(); - assert_eq!(test_str, "-"); + assert_eq!(Service::NotApplicable.to_string(), "-"); } #[test] fn test_service_display_known() { - let test_str = Service::Name("https").to_string(); - assert_eq!(test_str, "https"); + assert_eq!(Service::Name("https").to_string(), "https"); + assert_eq!(Service::Name("mpp").to_string(), "mpp"); + } + + #[test] + fn test_service_to_string_with_equal_prefix() { + assert_eq!(Service::Name("mdns").to_string_with_equal_prefix(), "=mdns"); + assert_eq!(Service::Name("upnp").to_string_with_equal_prefix(), "=upnp"); + assert_eq!(Service::NotApplicable.to_string_with_equal_prefix(), "=-"); + // unknown should not have the prefix + assert_eq!(Service::Unknown.to_string_with_equal_prefix(), "?"); } } diff --git a/src/report/types/report_col.rs b/src/report/types/report_col.rs index 300228db..a4c7a377 100644 --- a/src/report/types/report_col.rs +++ b/src/report/types/report_col.rs @@ -123,7 +123,7 @@ pub(crate) fn get_filter_input_type(&self) -> FilterInputType { ReportCol::SrcPort => FilterInputType::PortSrc, ReportCol::DstPort => FilterInputType::PortDst, ReportCol::Proto => FilterInputType::Proto, - ReportCol::Service => FilterInputType::AppProto, + ReportCol::Service => FilterInputType::Service, ReportCol::Bytes | ReportCol::Packets => FilterInputType::Country, // just to not panic... } } diff --git a/src/report/types/search_parameters.rs b/src/report/types/search_parameters.rs index 119063f9..04de118c 100644 --- a/src/report/types/search_parameters.rs +++ b/src/report/types/search_parameters.rs @@ -15,7 +15,7 @@ pub struct SearchParameters { pub port_dst: String, /// Protocol pub proto: String, - /// Application protocol + /// Service pub service: String, /// Country pub country: String, @@ -80,7 +80,7 @@ pub enum FilterInputType { AddressDst, PortDst, Proto, - AppProto, + Service, Country, Domain, AsName, @@ -93,7 +93,7 @@ impl FilterInputType { Self::AddressDst, Self::PortDst, Self::Proto, - Self::AppProto, + Self::Service, Self::Country, Self::Domain, Self::AsName, @@ -118,17 +118,7 @@ pub fn matches_entry( return entry_value.eq(stripped_filter); } - match self { - FilterInputType::AddressSrc - | FilterInputType::AddressDst - | FilterInputType::Domain - | FilterInputType::AsName => entry_value.contains(&filter_value), - FilterInputType::PortSrc - | FilterInputType::PortDst - | FilterInputType::Proto - | FilterInputType::AppProto - | FilterInputType::Country => entry_value.starts_with(&filter_value), - } + entry_value.contains(&filter_value) } pub fn current_value(self, search_params: &SearchParameters) -> &str { @@ -138,7 +128,7 @@ pub fn current_value(self, search_params: &SearchParameters) -> &str { FilterInputType::AddressDst => &search_params.address_dst, FilterInputType::PortDst => &search_params.port_dst, FilterInputType::Proto => &search_params.proto, - FilterInputType::AppProto => &search_params.service, + FilterInputType::Service => &search_params.service, FilterInputType::Country => &search_params.country, FilterInputType::Domain => &search_params.domain, FilterInputType::AsName => &search_params.as_name, @@ -169,7 +159,7 @@ pub fn entry_value( } } FilterInputType::Proto => key.protocol.to_string(), - FilterInputType::AppProto => value.service.to_string(), + FilterInputType::Service => value.service.to_string(), FilterInputType::Country => r_dns_host.unwrap().1.country.to_string(), FilterInputType::Domain => r_dns_host.unwrap().0.to_string(), FilterInputType::AsName => r_dns_host.unwrap().1.asn.name.to_string(), @@ -198,7 +188,7 @@ pub fn clear_search(self, search_params: &SearchParameters) -> SearchParameters proto: String::new(), ..search_params.clone() }, - FilterInputType::AppProto => SearchParameters { + FilterInputType::Service => SearchParameters { service: String::new(), ..search_params.clone() }, @@ -243,7 +233,7 @@ pub fn new_search( proto: new_value.trim().to_string(), ..search_params.clone() }, - FilterInputType::AppProto => SearchParameters { + FilterInputType::Service => SearchParameters { service: new_value.trim().to_string(), ..search_params.clone() },