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

[pull] main from GyulyVGC:main #171

Merged
merged 14 commits into from
Mar 23, 2024
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
All Sniffnet releases with the relative changes are documented in this file.

## [UNRELEASED]
- Introduced thumbnail mode, enabling users to keep an eye on Sniffnet while doing other tasks ([#484](https://github.com/GyulyVGC/sniffnet/pull/484))
- Added support for ICMP connections and messages ([#417](https://github.com/GyulyVGC/sniffnet/pull/417) — fixes [#288](https://github.com/GyulyVGC/sniffnet/issues/288))
- Added capability to identify 6000+ upper layer services, protocols, trojans, and worms ([#450](https://github.com/GyulyVGC/sniffnet/pull/450) — fixes [#374](https://github.com/GyulyVGC/sniffnet/issues/374))
- Added feature to optionally export the analysis as a PCAP file with a custom path ([#473](https://github.com/GyulyVGC/sniffnet/pull/473) — fixes [#162](https://github.com/GyulyVGC/sniffnet/issues/162) and [#291](https://github.com/GyulyVGC/sniffnet/issues/291))
Expand Down
Binary file modified resources/fonts/subset/icons.ttf
Binary file not shown.
1 change: 1 addition & 0 deletions src/chart/manage_chart_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ mod tests {
language: Language::default(),
chart_type: ChartType::Packets,
style: StyleType::default(),
thumbnail: false,
};
let mut runtime_data = RunTimeData {
all_bytes: 0,
Expand Down
53 changes: 38 additions & 15 deletions src/chart/types/traffic_chart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ pub struct TrafficChart {
pub chart_type: ChartType,
/// Style of the chart
pub style: StyleType,
/// Whether the chart is for the thumbnail page
pub thumbnail: bool,
}

impl TrafficChart {
Expand All @@ -59,6 +61,7 @@ impl TrafficChart {
language,
chart_type: ChartType::Bytes,
style,
thumbnail: false,
}
}

Expand All @@ -78,6 +81,24 @@ impl TrafficChart {
self.style = style;
}

fn set_margins_and_label_areas<DB: DrawingBackend>(
&self,
chart_builder: &mut ChartBuilder<DB>,
) {
if self.thumbnail {
chart_builder.margin_right(0);
chart_builder.margin_left(0);
chart_builder.margin_bottom(0);
chart_builder.margin_top(5);
} else {
chart_builder
.margin_right(25)
.margin_top(6)
.set_label_area_size(LabelAreaPosition::Left, 55)
.set_label_area_size(LabelAreaPosition::Bottom, 40);
}
}

fn x_axis_range(&self) -> Range<f32> {
let first_time_displayed = if self.ticks > 30 { self.ticks - 30 } else { 0 };
let tot_seconds = self.ticks - 1;
Expand Down Expand Up @@ -156,22 +177,22 @@ impl Chart<Message> for TrafficChart {
return;
}

chart_builder
.margin_right(25)
.margin_top(6)
.set_label_area_size(LabelAreaPosition::Left, 55)
.set_label_area_size(LabelAreaPosition::Bottom, 40);
self.set_margins_and_label_areas(&mut chart_builder);

let x_axis_range = self.x_axis_range();
let y_axis_range = self.y_axis_range();

let x_labels = if self.ticks == 1 {
let x_labels = if self.ticks == 1 || self.thumbnail {
0
} else {
self.ticks as usize
};
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
let y_labels = 1 + (y_axis_range.end - y_axis_range.start) as usize;
let y_labels = if self.thumbnail {
0
} else {
1 + (y_axis_range.end - y_axis_range.start) as usize
};

let mut chart = chart_builder
.build_cartesian_2d(x_axis_range, y_axis_range)
Expand Down Expand Up @@ -212,14 +233,16 @@ impl Chart<Message> for TrafficChart {
}

// chart legend
chart
.configure_series_labels()
.position(SeriesLabelPosition::UpperRight)
.background_style(buttons_color.mix(0.6))
.border_style(buttons_color.stroke_width(CHARTS_LINE_BORDER * 2))
.label_font(self.font(13.5))
.draw()
.expect("Error drawing graph");
if !self.thumbnail {
chart
.configure_series_labels()
.position(SeriesLabelPosition::UpperRight)
.background_style(buttons_color.mix(0.6))
.border_style(buttons_color.stroke_width(CHARTS_LINE_BORDER * 2))
.label_font(self.font(13.5))
.draw()
.expect("Error drawing graph");
}
}
}

Expand Down
1 change: 1 addition & 0 deletions src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ mod tests {
window: ConfigWindow {
position: (440, 99),
size: (452, 870),
thumbnail_position: (20, 20),
},
};
// we want to be sure that modified config is different from defaults
Expand Down
48 changes: 47 additions & 1 deletion src/configs/types/config_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,14 @@ use crate::SNIFFNET_LOWERCASE;
pub struct ConfigWindow {
pub position: (i32, i32),
pub size: (u32, u32),
pub thumbnail_position: (i32, i32),
}

impl ConfigWindow {
pub const DEFAULT_SIZE: (u32, u32) = (1190, 670);
pub const MIN_SIZE: (u32, u32) = (800, 500);
const THUMBNAIL_SIZE: (u32, u32) = (360, 222);

const FILE_NAME: &'static str = "window";
#[cfg(not(test))]
pub fn load() -> Self {
Expand All @@ -28,13 +33,18 @@ impl ConfigWindow {
pub fn store(self) {
confy::store(SNIFFNET_LOWERCASE, Self::FILE_NAME, self).unwrap_or(());
}

pub fn thumbnail_size(factor: f64) -> (u32, u32) {
Self::THUMBNAIL_SIZE.scale(factor)
}
}

impl Default for ConfigWindow {
fn default() -> Self {
Self {
position: (0, 0),
size: (1190, 670),
size: ConfigWindow::DEFAULT_SIZE,
thumbnail_position: (0, 0),
}
}
}
Expand All @@ -53,6 +63,20 @@ impl ToPosition for (i32, i32) {
}
}

pub trait ToPoint {
fn to_point(self) -> Point;
}

impl ToPoint for (i32, i32) {
fn to_point(self) -> Point {
#[allow(clippy::cast_precision_loss)]
Point {
x: self.0 as f32,
y: self.1 as f32,
}
}
}

pub trait ToSize {
fn to_size(self) -> Size;
}
Expand All @@ -67,6 +91,28 @@ impl ToSize for (u32, u32) {
}
}

pub trait Scale {
fn scale(self, factor: f64) -> Self;
}

impl Scale for (u32, u32) {
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
fn scale(self, factor: f64) -> (u32, u32) {
let x = (f64::from(self.0) * factor) as u32;
let y = (f64::from(self.1) * factor) as u32;
(x, y)
}
}

impl Scale for (i32, i32) {
#[allow(clippy::cast_possible_truncation)]
fn scale(self, factor: f64) -> (i32, i32) {
let x = (f64::from(self.0) * factor) as i32;
let y = (f64::from(self.1) * factor) as i32;
(x, y)
}
}

#[cfg(test)]
mod tests {
use crate::ConfigWindow;
Expand Down
17 changes: 14 additions & 3 deletions src/countries/country_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,11 +318,16 @@ fn get_flag_from_country(

pub fn get_flag_tooltip(
country: Country,
width: f32,
host_info: &DataInfoHost,
language: Language,
font: Font,
thumbnail: bool,
) -> Tooltip<'static, Message, StyleType> {
let width = if thumbnail {
FLAGS_WIDTH_SMALL
} else {
FLAGS_WIDTH_BIG
};
let is_local = host_info.is_local;
let is_loopback = host_info.is_loopback;
let traffic_type = host_info.traffic_type;
Expand All @@ -335,13 +340,19 @@ pub fn get_flag_tooltip(
language,
);

let actual_tooltip = if thumbnail { String::new() } else { tooltip };
let tooltip_style = if thumbnail {
ContainerType::Standard
} else {
ContainerType::Tooltip
};
let mut tooltip = Tooltip::new(
content,
Text::new(tooltip).font(font),
Text::new(actual_tooltip).font(font),
Position::FollowCursor,
)
.snap_within_viewport(true)
.style(ContainerType::Tooltip);
.style(tooltip_style);

if width == FLAGS_WIDTH_SMALL {
tooltip = tooltip.padding(3);
Expand Down
55 changes: 35 additions & 20 deletions src/gui/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::time::Duration;

use iced::keyboard::key::Named;
use iced::keyboard::{Event, Key, Modifiers};
use iced::mouse::Event::ButtonPressed;
use iced::widget::Column;
use iced::window::Id;
use iced::Event::{Keyboard, Window};
Expand All @@ -23,6 +24,7 @@ use crate::gui::pages::overview_page::overview_page;
use crate::gui::pages::settings_general_page::settings_general_page;
use crate::gui::pages::settings_notifications_page::settings_notifications_page;
use crate::gui::pages::settings_style_page::settings_style_page;
use crate::gui::pages::thumbnail_page::thumbnail_page;
use crate::gui::pages::types::running_page::RunningPage;
use crate::gui::pages::types::settings_page::SettingsPage;
use crate::gui::types::message::Message;
Expand Down Expand Up @@ -63,22 +65,21 @@ impl Application for Sniffer {
let font = style.get_extension().font;
let font_headers = style.get_extension().font_headers;

let header = header(
font,
color_gradient,
self.running_page.ne(&RunningPage::Init),
language,
self.last_opened_setting,
);
let header = header(self);

let body = match self.running_page {
RunningPage::Init => initial_page(self),
RunningPage::Overview => overview_page(self),
RunningPage::Inspect => inspect_page(self),
RunningPage::Notifications => notifications_page(self),
let body = if self.thumbnail {
thumbnail_page(self)
} else {
match self.running_page {
RunningPage::Init => initial_page(self),
RunningPage::Overview => overview_page(self),
RunningPage::Inspect => inspect_page(self),
RunningPage::Notifications => notifications_page(self),
}
};

let footer = footer(
self.thumbnail,
language,
color_gradient,
font,
Expand Down Expand Up @@ -122,7 +123,9 @@ impl Application for Sniffer {

fn subscription(&self) -> Subscription<Message> {
const NO_MODIFIER: Modifiers = Modifiers::empty();
let window_events_subscription = iced::event::listen_with(|event, _| match event {

// Window subscription
let window_sub = iced::event::listen_with(|event, _| match event {
Window(Id::MAIN, window::Event::Focused) => Some(Message::WindowFocused),
Window(Id::MAIN, window::Event::Moved { x, y }) => Some(Message::WindowMoved(x, y)),
Window(Id::MAIN, window::Event::Resized { width, height }) => {
Expand All @@ -131,7 +134,9 @@ impl Application for Sniffer {
Window(Id::MAIN, window::Event::CloseRequested) => Some(Message::CloseRequested),
_ => None,
});
let hot_keys_subscription = iced::event::listen_with(|event, _| match event {

// Keyboard subscription
let keyboard_sub = iced::event::listen_with(|event, _| match event {
Keyboard(Event::KeyPressed { key, modifiers, .. }) => match modifiers {
Modifiers::COMMAND => match key.as_ref() {
Key::Character("q") => Some(Message::CloseRequested),
Expand All @@ -156,17 +161,27 @@ impl Application for Sniffer {
},
_ => None,
});
let time_subscription = if self.running_page.eq(&RunningPage::Init) {

// Mouse subscription
let mouse_sub = iced::event::listen_with(|event, _| match event {
iced::event::Event::Mouse(ButtonPressed(_)) => Some(Message::Drag),
_ => None,
});

// Time subscription
let time_sub = if self.running_page.eq(&RunningPage::Init) {
iced::time::every(Duration::from_millis(PERIOD_TICK)).map(|_| Message::TickInit)
} else {
iced::time::every(Duration::from_millis(PERIOD_TICK)).map(|_| Message::TickRun)
};

Subscription::batch([
window_events_subscription,
hot_keys_subscription,
time_subscription,
])
let mut subscriptions = Vec::from([window_sub, time_sub]);
if self.thumbnail {
subscriptions.push(mouse_sub);
} else {
subscriptions.push(keyboard_sub);
}
Subscription::batch(subscriptions)
}

fn theme(&self) -> Self::Theme {
Expand Down
2 changes: 1 addition & 1 deletion src/gui/components/button.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pub fn button_open_file(
action: fn(String) -> Message,
) -> Tooltip<'static, Message, StyleType> {
let mut tooltip_str = "";
let mut tooltip_style = ContainerType::Neutral;
let mut tooltip_style = ContainerType::Standard;

let mut button = button(
Icon::File
Expand Down
11 changes: 10 additions & 1 deletion src/gui/components/footer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use std::sync::{Arc, Mutex};
use iced::alignment::{Horizontal, Vertical};
use iced::widget::text::LineHeight;
use iced::widget::tooltip::Position;
use iced::widget::Space;
use iced::widget::{button, Container, Row, Text, Tooltip};
use iced::widget::{horizontal_space, Space};
use iced::{Alignment, Font, Length};

use crate::gui::components::button::row_open_link_tooltip;
Expand All @@ -24,12 +24,17 @@ use crate::utils::types::web_page::WebPage;
use crate::{Language, SNIFFNET_TITLECASE};

pub fn footer(
thumbnail: bool,
language: Language,
color_gradient: GradientType,
font: Font,
font_footer: Font,
newer_release_available: &Arc<Mutex<Option<bool>>>,
) -> Container<'static, Message, StyleType> {
if thumbnail {
return thumbnail_footer();
}

let release_details_row =
get_release_details(language, font, font_footer, newer_release_available);

Expand Down Expand Up @@ -165,3 +170,7 @@ fn get_release_details(
}
ret_val
}

fn thumbnail_footer() -> Container<'static, Message, StyleType> {
Container::new(horizontal_space()).height(0)
}
Loading