From efc363524656120575e85a0d0d68206401c37e38 Mon Sep 17 00:00:00 2001 From: DaLaw2 Date: Fri, 29 Nov 2024 17:39:41 +0800 Subject: [PATCH] Complete monitor get flow state APIs --- Cargo.lock | 64 ++++++++++- Cargo.toml | 4 +- .../model/{flow_status.rs => flow_stats.rs} | 4 +- net-guardia-common/src/model/mod.rs | 2 +- net-guardia-ebpf/src/action/monitor.rs | 64 ++++++----- net-guardia-ebpf/src/utils/parsing.rs | 4 +- net-guardia/Cargo.toml | 2 + net-guardia/build.rs | 6 +- net-guardia/src/core/monitor.rs | 42 +++---- net-guardia/src/model/flow_stats.rs | 25 ++++ net-guardia/src/model/flow_type.rs | 1 + net-guardia/src/model/ip_address.rs | 35 ++++++ net-guardia/src/model/mod.rs | 2 + net-guardia/src/utils/definition.rs | 3 + net-guardia/src/utils/mod.rs | 1 + net-guardia/src/web/api/monitor.rs | 107 +++++++++++++++++- net-guardia/src/web/utils/flow_websocket.rs | 34 ++++++ net-guardia/src/web/utils/map_util.rs | 25 ++++ net-guardia/src/web/utils/mod.rs | 3 +- 19 files changed, 364 insertions(+), 64 deletions(-) rename net-guardia-common/src/model/{flow_status.rs => flow_stats.rs} (94%) create mode 100644 net-guardia/src/model/flow_stats.rs create mode 100644 net-guardia/src/model/ip_address.rs create mode 100644 net-guardia/src/utils/definition.rs create mode 100644 net-guardia/src/web/utils/map_util.rs diff --git a/Cargo.lock b/Cargo.lock index 6c568ef..b33dac2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,31 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "actix" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de7fa236829ba0841304542f7614c42b80fca007455315c45c785ccfa873a85b" +dependencies = [ + "actix-macros", + "actix-rt", + "actix_derive", + "bitflags", + "bytes", + "crossbeam-channel", + "futures-core", + "futures-sink", + "futures-task", + "futures-util", + "log", + "once_cell", + "parking_lot", + "pin-project-lite", + "smallvec", + "tokio", + "tokio-util", +] + [[package]] name = "actix-codec" version = "0.5.2" @@ -188,6 +213,24 @@ dependencies = [ "url", ] +[[package]] +name = "actix-web-actors" +version = "4.3.1+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98c5300b38fd004fe7d2a964f9a90813fdbe8a81fed500587e78b1b71c6f980" +dependencies = [ + "actix", + "actix-codec", + "actix-http", + "actix-web", + "bytes", + "bytestring", + "futures-core", + "pin-project-lite", + "tokio", + "tokio-util", +] + [[package]] name = "actix-web-codegen" version = "4.3.0" @@ -200,6 +243,17 @@ dependencies = [ "syn", ] +[[package]] +name = "actix_derive" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6ac1e58cded18cb28ddc17143c4dea5345b3ad575e14f32f66e4054a56eb271" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "addr2line" version = "0.24.2" @@ -501,9 +555,9 @@ dependencies = [ [[package]] name = "cargo_metadata" -version = "0.18.1" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +checksum = "afc309ed89476c8957c50fb818f56fe894db857866c3e163335faa91dc34eb85" dependencies = [ "camino", "cargo-platform", @@ -1120,8 +1174,10 @@ dependencies = [ name = "net-guardia" version = "0.1.0" dependencies = [ + "actix", "actix-cors", "actix-web", + "actix-web-actors", "anyhow", "aya", "aya-log", @@ -1982,9 +2038,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "which" -version = "6.0.3" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ee928febd44d98f2f459a4a79bd4d928591333a494a10a868418ac1b39cf1f" +checksum = "c9cad3279ade7346b96e38731a641d7343dd6a53d55083dd54eadfa5a1b38c6b" dependencies = [ "either", "home", diff --git a/Cargo.toml b/Cargo.toml index c6c92ab..68669ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ aya-log = { version = "0.2.1", default-features = false } aya-log-ebpf = { version = "0.1.1", default-features = false } anyhow = { version = "1", default-features = false } -cargo_metadata = { version = "0.18.0", default-features = false } +cargo_metadata = { version = "0.19.0", default-features = false } # `std` feature is currently required to build `clap`. # # See https://github.com/clap-rs/clap/blob/61f5ee5/clap_builder/src/lib.rs#L15. @@ -19,7 +19,7 @@ env_logger = { version = "0.11.5", default-features = false } libc = { version = "0.2.159", default-features = false } log = { version = "0.4.22", default-features = false } tokio = { version = "1.40.0", default-features = false } -which = { version = "6.0.0", default-features = false } +which = { version = "7.0.0", default-features = false } [profile.dev] panic = "abort" diff --git a/net-guardia-common/src/model/flow_status.rs b/net-guardia-common/src/model/flow_stats.rs similarity index 94% rename from net-guardia-common/src/model/flow_status.rs rename to net-guardia-common/src/model/flow_stats.rs index ab6bfd2..bf0f539 100644 --- a/net-guardia-common/src/model/flow_status.rs +++ b/net-guardia-common/src/model/flow_stats.rs @@ -11,7 +11,7 @@ /// ```ignore /// // Create new flow status /// let now = bpf_ktime_get_ns(); -/// let status: FlowStatus = [ +/// let status: FlowStats = [ /// 1500, // 1500 bytes /// 1, // 1 packet /// now, // Current timestamp @@ -34,4 +34,4 @@ /// [1]: [------------------ Packets (64 bits) -----------------] /// [2]: [----------------- Timestamp (64 bits) ----------------] /// ``` -pub type FlowStatus = [u64; 3]; +pub type FlowStats = [u64; 3]; diff --git a/net-guardia-common/src/model/mod.rs b/net-guardia-common/src/model/mod.rs index 8e9eab3..de95584 100644 --- a/net-guardia-common/src/model/mod.rs +++ b/net-guardia-common/src/model/mod.rs @@ -1,5 +1,5 @@ pub mod event; -pub mod flow_status; +pub mod flow_stats; pub mod ip_address; pub mod packet_status; pub mod pseudo_header; diff --git a/net-guardia-ebpf/src/action/monitor.rs b/net-guardia-ebpf/src/action/monitor.rs index 683dade..e44150b 100644 --- a/net-guardia-ebpf/src/action/monitor.rs +++ b/net-guardia-ebpf/src/action/monitor.rs @@ -2,46 +2,58 @@ use aya_ebpf::helpers::bpf_ktime_get_ns; use aya_ebpf::macros::map; use aya_ebpf::maps::LruHashMap; use net_guardia_common::model::event::{IPv4Event, IPv6Event}; -use net_guardia_common::model::flow_status::FlowStatus; +use net_guardia_common::model::flow_stats::FlowStats; use net_guardia_common::model::ip_address::{AddrPortV4, AddrPortV6}; use net_guardia_common::MAX_STATS; #[map] -static SRC_IPV4_1MIN: LruHashMap = LruHashMap::with_max_entries(MAX_STATS, 0); +static SRC_IPV4_1MIN: LruHashMap = + LruHashMap::with_max_entries(MAX_STATS, 0); #[map] -static SRC_IPV6_1MIN: LruHashMap = LruHashMap::with_max_entries(MAX_STATS, 0); +static SRC_IPV4_10MIN: LruHashMap = + LruHashMap::with_max_entries(MAX_STATS, 0); #[map] -static SRC_IPV4_10MIN: LruHashMap = LruHashMap::with_max_entries(MAX_STATS, 0); +static SRC_IPV4_1HOUR: LruHashMap = + LruHashMap::with_max_entries(MAX_STATS, 0); #[map] -static SRC_IPV6_10MIN: LruHashMap = LruHashMap::with_max_entries(MAX_STATS, 0); +static SRC_IPV6_1MIN: LruHashMap = + LruHashMap::with_max_entries(MAX_STATS, 0); #[map] -static SRC_IPV4_1HOUR: LruHashMap = LruHashMap::with_max_entries(MAX_STATS, 0); +static SRC_IPV6_10MIN: LruHashMap = + LruHashMap::with_max_entries(MAX_STATS, 0); #[map] -static SRC_IPV6_1HOUR: LruHashMap = LruHashMap::with_max_entries(MAX_STATS, 0); +static SRC_IPV6_1HOUR: LruHashMap = + LruHashMap::with_max_entries(MAX_STATS, 0); #[map] -static DST_IPV4_1MIN: LruHashMap = LruHashMap::with_max_entries(MAX_STATS, 0); +static DST_IPV4_1MIN: LruHashMap = + LruHashMap::with_max_entries(MAX_STATS, 0); #[map] -static DST_IPV6_1MIN: LruHashMap = LruHashMap::with_max_entries(MAX_STATS, 0); +static DST_IPV4_10MIN: LruHashMap = + LruHashMap::with_max_entries(MAX_STATS, 0); #[map] -static DST_IPV4_10MIN: LruHashMap = LruHashMap::with_max_entries(MAX_STATS, 0); +static DST_IPV4_1HOUR: LruHashMap = + LruHashMap::with_max_entries(MAX_STATS, 0); #[map] -static DST_IPV6_10MIN: LruHashMap = LruHashMap::with_max_entries(MAX_STATS, 0); +static DST_IPV6_1MIN: LruHashMap = + LruHashMap::with_max_entries(MAX_STATS, 0); #[map] -static DST_IPV4_1HOUR: LruHashMap = LruHashMap::with_max_entries(MAX_STATS, 0); +static DST_IPV6_10MIN: LruHashMap = + LruHashMap::with_max_entries(MAX_STATS, 0); #[map] -static DST_IPV6_1HOUR: LruHashMap = LruHashMap::with_max_entries(MAX_STATS, 0); +static DST_IPV6_1HOUR: LruHashMap = + LruHashMap::with_max_entries(MAX_STATS, 0); pub fn update_stats_ipv4(event: &IPv4Event) { unsafe { let now = bpf_ktime_get_ns(); let source = [event.source_ip, event.source_port as u32]; let destination = [event.destination_ip, event.destination_port as u32]; - update_flow_status_ipv4(&SRC_IPV4_1MIN, &source, event, now); - update_flow_status_ipv4(&SRC_IPV4_10MIN, &source, event, now); - update_flow_status_ipv4(&SRC_IPV4_1HOUR, &source, event, now); - update_flow_status_ipv4(&DST_IPV4_1MIN, &destination, event, now); - update_flow_status_ipv4(&DST_IPV4_10MIN, &destination, event, now); - update_flow_status_ipv4(&DST_IPV4_1HOUR, &destination, event, now); + update_flow_stats_ipv4(&SRC_IPV4_1MIN, &source, event, now); + update_flow_stats_ipv4(&SRC_IPV4_10MIN, &source, event, now); + update_flow_stats_ipv4(&SRC_IPV4_1HOUR, &source, event, now); + update_flow_stats_ipv4(&DST_IPV4_1MIN, &destination, event, now); + update_flow_stats_ipv4(&DST_IPV4_10MIN, &destination, event, now); + update_flow_stats_ipv4(&DST_IPV4_1HOUR, &destination, event, now); } } @@ -60,8 +72,8 @@ pub fn update_stats_ipv6(event: &IPv6Event) { } #[inline(always)] -unsafe fn update_flow_status_ipv4( - map: &LruHashMap, +unsafe fn update_flow_stats_ipv4( + map: &LruHashMap, key: &AddrPortV4, event: &IPv4Event, now: u64, @@ -71,14 +83,14 @@ unsafe fn update_flow_status_ipv4( (*status)[1] += 1; (*status)[2] = now; } else { - let new_status = [event.len as u64, 1, now]; - let _ = map.insert(key, &new_status, 0); + let new_stats = [event.len as u64, 1, now]; + let _ = map.insert(key, &new_stats, 0); } } #[inline(always)] unsafe fn update_flow_status_ipv6( - map: &LruHashMap, + map: &LruHashMap, key: &AddrPortV6, event: &IPv6Event, now: u64, @@ -88,7 +100,7 @@ unsafe fn update_flow_status_ipv6( (*status)[1] += 1; (*status)[2] = now; } else { - let new_status = [event.len as u64, 1, now]; - let _ = map.insert(key, &new_status, 0); + let new_stats = [event.len as u64, 1, now]; + let _ = map.insert(key, &new_stats, 0); } } diff --git a/net-guardia-ebpf/src/utils/parsing.rs b/net-guardia-ebpf/src/utils/parsing.rs index be81739..d010d35 100644 --- a/net-guardia-ebpf/src/utils/parsing.rs +++ b/net-guardia-ebpf/src/utils/parsing.rs @@ -38,8 +38,8 @@ pub fn parse_ipv4_packet(ctx: &XdpContext) -> Result { offset += size_of::(); let protocol = ipv4.proto; - let source_ip = ipv4.src_addr; - let destination_ip = ipv4.dst_addr; + let source_ip = u32::from_be(ipv4.src_addr); + let destination_ip = u32::from_be(ipv4.dst_addr); let (source_port, destination_port) = match protocol { IpProto::Tcp => parse_tcp_port(start, end, offset)?, diff --git a/net-guardia/Cargo.toml b/net-guardia/Cargo.toml index e89e23b..3f893cb 100644 --- a/net-guardia/Cargo.toml +++ b/net-guardia/Cargo.toml @@ -20,7 +20,9 @@ tracing-appender = "0.2.3" actix-web = "4.9.0" rust-embed = "8.5.0" actix-cors = "0.7.0" +actix = "0.13.5" mime_guess = "2.0.5" +actix-web-actors = "4.3.0" [build-dependencies] cargo_metadata = { workspace = true } diff --git a/net-guardia/build.rs b/net-guardia/build.rs index e744ad1..0746bde 100644 --- a/net-guardia/build.rs +++ b/net-guardia/build.rs @@ -5,9 +5,7 @@ use std::{ process::{Child, Command, Stdio}, }; -use cargo_metadata::{ - Artifact, CompilerMessage, Message, Metadata, MetadataCommand, Package, Target, -}; +use cargo_metadata::{Artifact, CompilerMessage, Message, Metadata, MetadataCommand, Package, Target, TargetKind}; /// This crate has a runtime dependency on artifacts produced by the `net-guardia-ebpf` crate. /// This would be better expressed as one or more [artifact-dependencies][bindeps] but issues such @@ -140,7 +138,7 @@ fn main() { } else { let Package { targets, .. } = ebpf_package; for Target { name, kind, .. } in targets { - if *kind != ["bin"] { + if *kind != [TargetKind::Bin] { continue; } let dst = out_dir.join(name); diff --git a/net-guardia/src/core/monitor.rs b/net-guardia/src/core/monitor.rs index 000d639..73caf86 100644 --- a/net-guardia/src/core/monitor.rs +++ b/net-guardia/src/core/monitor.rs @@ -2,8 +2,10 @@ use crate::core::system::System; use crate::model::flow_type::{IPv4FlowType, IPv6FlowType}; use crate::utils::log_entry::system::SystemEntry; use aya::maps::{HashMap as AyaHashMap, MapData}; -use net_guardia_common::model::flow_status::FlowStatus; -use net_guardia_common::model::ip_address::{AddrPortV4, AddrPortV6}; +use net_guardia_common::model::flow_stats::FlowStats as EbpfFlowStats; +use net_guardia_common::model::ip_address::{ + AddrPortV4 as EbpfAddrPortV4, AddrPortV6 as EbpfAddrPortV6, +}; use std::collections::HashMap as StdHashMap; use std::sync::OnceLock; use tokio::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard}; @@ -12,18 +14,18 @@ use tracing::info; static MONITOR: OnceLock> = OnceLock::new(); pub struct Monitor { - src_ipv4_1min: AyaHashMap, - src_ipv6_1min: AyaHashMap, - src_ipv4_10min: AyaHashMap, - src_ipv6_10min: AyaHashMap, - src_ipv4_1hour: AyaHashMap, - src_ipv6_1hour: AyaHashMap, - dst_ipv4_1min: AyaHashMap, - dst_ipv6_1min: AyaHashMap, - dst_ipv4_10min: AyaHashMap, - dst_ipv6_10min: AyaHashMap, - dst_ipv4_1hour: AyaHashMap, - dst_ipv6_1hour: AyaHashMap, + src_ipv4_1min: AyaHashMap, + src_ipv4_10min: AyaHashMap, + src_ipv4_1hour: AyaHashMap, + src_ipv6_1min: AyaHashMap, + src_ipv6_10min: AyaHashMap, + src_ipv6_1hour: AyaHashMap, + dst_ipv4_1min: AyaHashMap, + dst_ipv4_10min: AyaHashMap, + dst_ipv4_1hour: AyaHashMap, + dst_ipv6_1min: AyaHashMap, + dst_ipv6_10min: AyaHashMap, + dst_ipv6_1hour: AyaHashMap, } impl Monitor { @@ -33,16 +35,16 @@ impl Monitor { let mut ebpf = &mut system.ebpf; let monitor = Monitor { src_ipv4_1min: AyaHashMap::try_from(ebpf.take_map("SRC_IPV4_1MIN").unwrap())?, - src_ipv6_1min: AyaHashMap::try_from(ebpf.take_map("SRC_IPV6_1MIN").unwrap())?, src_ipv4_10min: AyaHashMap::try_from(ebpf.take_map("SRC_IPV4_10MIN").unwrap())?, - src_ipv6_10min: AyaHashMap::try_from(ebpf.take_map("SRC_IPV6_10MIN").unwrap())?, src_ipv4_1hour: AyaHashMap::try_from(ebpf.take_map("SRC_IPV4_1HOUR").unwrap())?, + src_ipv6_1min: AyaHashMap::try_from(ebpf.take_map("SRC_IPV6_1MIN").unwrap())?, + src_ipv6_10min: AyaHashMap::try_from(ebpf.take_map("SRC_IPV6_10MIN").unwrap())?, src_ipv6_1hour: AyaHashMap::try_from(ebpf.take_map("SRC_IPV6_1HOUR").unwrap())?, dst_ipv4_1min: AyaHashMap::try_from(ebpf.take_map("DST_IPV4_1MIN").unwrap())?, - dst_ipv6_1min: AyaHashMap::try_from(ebpf.take_map("DST_IPV6_1MIN").unwrap())?, dst_ipv4_10min: AyaHashMap::try_from(ebpf.take_map("DST_IPV4_10MIN").unwrap())?, - dst_ipv6_10min: AyaHashMap::try_from(ebpf.take_map("DST_IPV6_10MIN").unwrap())?, dst_ipv4_1hour: AyaHashMap::try_from(ebpf.take_map("DST_IPV4_1HOUR").unwrap())?, + dst_ipv6_1min: AyaHashMap::try_from(ebpf.take_map("DST_IPV6_1MIN").unwrap())?, + dst_ipv6_10min: AyaHashMap::try_from(ebpf.take_map("DST_IPV6_10MIN").unwrap())?, dst_ipv6_1hour: AyaHashMap::try_from(ebpf.take_map("DST_IPV6_1HOUR").unwrap())?, }; MONITOR.get_or_init(|| RwLock::new(monitor)); @@ -68,7 +70,7 @@ impl Monitor { pub async fn get_ipv4_flow_data( ipv4_flow_type: IPv4FlowType, - ) -> StdHashMap { + ) -> StdHashMap { let monitor = Monitor::instance().await; let iter = match ipv4_flow_type { IPv4FlowType::SrcIPv4_1Min => monitor.src_ipv4_1min.iter(), @@ -83,7 +85,7 @@ impl Monitor { pub async fn get_ipv6_flow_data( ipv6_flow_type: IPv6FlowType, - ) -> StdHashMap { + ) -> StdHashMap { let monitor = Monitor::instance().await; let iter = match ipv6_flow_type { IPv6FlowType::SrcIPv6_1Min => monitor.src_ipv6_1min.iter(), diff --git a/net-guardia/src/model/flow_stats.rs b/net-guardia/src/model/flow_stats.rs new file mode 100644 index 0000000..ff79ecb --- /dev/null +++ b/net-guardia/src/model/flow_stats.rs @@ -0,0 +1,25 @@ +use serde::Serialize; +use net_guardia_common::model::flow_stats::FlowStats as EbpfFlowStats; + +#[derive(Serialize, Debug, Clone)] +pub struct FlowStats { + pub bytes: u64, + pub packets: u64, + pub last_seen: u64, +} + +impl From for FlowStats { + fn from(ebpf_flow_status: EbpfFlowStats) -> Self { + FlowStats { + bytes: ebpf_flow_status[0], + packets: ebpf_flow_status[1], + last_seen: ebpf_flow_status[2], + } + } +} + +impl From for EbpfFlowStats { + fn from(flow_status: FlowStats) -> Self { + [flow_status.bytes, flow_status.packets, flow_status.last_seen] + } +} diff --git a/net-guardia/src/model/flow_type.rs b/net-guardia/src/model/flow_type.rs index a27857d..fbb0d5f 100644 --- a/net-guardia/src/model/flow_type.rs +++ b/net-guardia/src/model/flow_type.rs @@ -7,6 +7,7 @@ pub enum IPv4FlowType { DstIPv4_10Min, DstIPv4_1Hour, } + #[derive(Copy, Clone)] pub enum IPv6FlowType { SrcIPv6_1Min, diff --git a/net-guardia/src/model/ip_address.rs b/net-guardia/src/model/ip_address.rs new file mode 100644 index 0000000..b31a5cc --- /dev/null +++ b/net-guardia/src/model/ip_address.rs @@ -0,0 +1,35 @@ +use std::net::{Ipv4Addr, Ipv6Addr}; +use serde::Serialize; +use net_guardia_common::model::ip_address::{ + AddrPortV4 as EbpfAddrPortV4, AddrPortV6 as EbpfAddrPortV6 +}; +use crate::utils::definition::IntoString; + +#[derive(Serialize, Debug, PartialEq, Eq, Hash)] +pub struct AddrPortV4 { + pub ip: u32, + pub port: u16, +} + + +#[derive(Serialize, Debug, PartialEq, Eq, Hash)] +pub struct AddrPortV6 { + pub ip: u128, + pub port: u16, +} + +impl IntoString for EbpfAddrPortV4 { + fn into_string(self) -> String { + let ip_addr = Ipv4Addr::from(self[0]); + let port = self[1] as u16; + format!("{}:{}", ip_addr, port) + } +} + +impl IntoString for EbpfAddrPortV6 { + fn into_string(self) -> String { + let ip_addr = Ipv6Addr::from(self[0]); + let port = self[1] as u16; + format!("[{}]:{}", ip_addr, port) + } +} diff --git a/net-guardia/src/model/mod.rs b/net-guardia/src/model/mod.rs index 39530a7..9245b19 100644 --- a/net-guardia/src/model/mod.rs +++ b/net-guardia/src/model/mod.rs @@ -1,2 +1,4 @@ pub mod config; +pub mod flow_stats; pub mod flow_type; +pub mod ip_address; diff --git a/net-guardia/src/utils/definition.rs b/net-guardia/src/utils/definition.rs new file mode 100644 index 0000000..72649a9 --- /dev/null +++ b/net-guardia/src/utils/definition.rs @@ -0,0 +1,3 @@ +pub trait IntoString { + fn into_string(self) -> String; +} diff --git a/net-guardia/src/utils/mod.rs b/net-guardia/src/utils/mod.rs index 1b887c3..2b9085c 100644 --- a/net-guardia/src/utils/mod.rs +++ b/net-guardia/src/utils/mod.rs @@ -1,3 +1,4 @@ pub mod log_entry; +pub mod definition; pub mod logging; pub mod static_files; diff --git a/net-guardia/src/web/api/monitor.rs b/net-guardia/src/web/api/monitor.rs index b865c13..1cb762d 100644 --- a/net-guardia/src/web/api/monitor.rs +++ b/net-guardia/src/web/api/monitor.rs @@ -1,6 +1,109 @@ -use crate::utils::static_files::StaticFiles; -use actix_web::{get, post, web, HttpResponse, Responder, Scope}; +use crate::core::monitor::Monitor; +use crate::model::flow_type::{IPv4FlowType, IPv6FlowType}; +use actix_web::{get, web, Error, HttpRequest, HttpResponse, Responder, Scope}; +use crate::web::utils::map_util::{transform_ipv4_flow_data, transform_ipv6_flow_data}; pub fn initialize() -> Scope { web::scope("/monitor") + .service(get_src_ipv4_1min) + .service(get_src_ipv4_10min) + .service(get_src_ipv4_1hour) + .service(get_src_ipv6_1min) + .service(get_src_ipv6_10min) + .service(get_src_ipv6_1hour) + .service(get_dst_ipv4_1min) + .service(get_dst_ipv4_10min) + .service(get_dst_ipv4_1hour) + .service(get_dst_ipv6_1min) + .service(get_dst_ipv6_10min) + .service(get_dst_ipv6_1hour) +} + +#[get("/get/src/ipv4/1min")] +async fn get_src_ipv4_1min() -> impl Responder { + let flow_data = Monitor::get_ipv4_flow_data(IPv4FlowType::SrcIPv4_1Min).await; + let formated = transform_ipv4_flow_data(flow_data); + HttpResponse::Ok().json(web::Json(formated)) +} + +#[get("/get/src/ipv4/10min")] +async fn get_src_ipv4_10min() -> impl Responder { + let flow_data = Monitor::get_ipv4_flow_data(IPv4FlowType::SrcIPv4_10Min).await; + let formated = transform_ipv4_flow_data(flow_data); + HttpResponse::Ok().json(web::Json(formated)) +} + +#[get("/get/src/ipv4/1hour")] +async fn get_src_ipv4_1hour() -> impl Responder { + let flow_data = Monitor::get_ipv4_flow_data(IPv4FlowType::SrcIPv4_1Hour).await; + let formated = transform_ipv4_flow_data(flow_data); + HttpResponse::Ok().json(web::Json(formated)) +} + +#[get("/get/src/ipv6/1min")] +async fn get_src_ipv6_1min() -> impl Responder { + let flow_data = Monitor::get_ipv6_flow_data(IPv6FlowType::SrcIPv6_1Min).await; + let formated = transform_ipv6_flow_data(flow_data); + HttpResponse::Ok().json(web::Json(formated)) +} + +#[get("/get/src/ipv6/10min")] +async fn get_src_ipv6_10min() -> impl Responder { + let flow_data = Monitor::get_ipv6_flow_data(IPv6FlowType::SrcIPv6_10Min).await; + let formated = transform_ipv6_flow_data(flow_data); + HttpResponse::Ok().json(web::Json(formated)) +} + +#[get("/get/src/ipv6/1hour")] +async fn get_src_ipv6_1hour() -> impl Responder { + let flow_data = Monitor::get_ipv6_flow_data(IPv6FlowType::SrcIPv6_1Hour).await; + let formated = transform_ipv6_flow_data(flow_data); + HttpResponse::Ok().json(web::Json(formated)) +} + +#[get("/get/dst/ipv4/1min")] +async fn get_dst_ipv4_1min() -> impl Responder { + let flow_data = Monitor::get_ipv4_flow_data(IPv4FlowType::DstIPv4_1Min).await; + let formated = transform_ipv4_flow_data(flow_data); + HttpResponse::Ok().json(web::Json(formated)) +} + +#[get("/get/dst/ipv4/10min")] +async fn get_dst_ipv4_10min() -> impl Responder { + let flow_data = Monitor::get_ipv4_flow_data(IPv4FlowType::DstIPv4_10Min).await; + let formated = transform_ipv4_flow_data(flow_data); + HttpResponse::Ok().json(web::Json(formated)) +} + +#[get("/get/dst/ipv4/1hour")] +async fn get_dst_ipv4_1hour() -> impl Responder { + let flow_data = Monitor::get_ipv4_flow_data(IPv4FlowType::DstIPv4_1Hour).await; + let formated = transform_ipv4_flow_data(flow_data); + HttpResponse::Ok().json(web::Json(formated)) +} + +#[get("/get/dst/ipv6/1min")] +async fn get_dst_ipv6_1min() -> impl Responder { + let flow_data = Monitor::get_ipv6_flow_data(IPv6FlowType::SrcIPv6_1Min).await; + let formated = transform_ipv6_flow_data(flow_data); + HttpResponse::Ok().json(web::Json(formated)) +} + +#[get("/get/dst/ipv6/10min")] +async fn get_dst_ipv6_10min() -> impl Responder { + let flow_data = Monitor::get_ipv6_flow_data(IPv6FlowType::SrcIPv6_10Min).await; + let formated = transform_ipv6_flow_data(flow_data); + HttpResponse::Ok().json(web::Json(formated)) +} + +#[get("/get/dst/ipv6/1hour")] +async fn get_dst_ipv6_1hour() -> impl Responder { + let flow_data = Monitor::get_ipv6_flow_data(IPv6FlowType::SrcIPv6_1Hour).await; + let formated = transform_ipv6_flow_data(flow_data); + HttpResponse::Ok().json(web::Json(formated)) +} + +#[get("/websocket")] +async fn websocket(req: HttpRequest, stream: web::Payload) -> Result { + Ok(HttpResponse::Forbidden().finish()) } diff --git a/net-guardia/src/web/utils/flow_websocket.rs b/net-guardia/src/web/utils/flow_websocket.rs index e69de29..f7b625c 100644 --- a/net-guardia/src/web/utils/flow_websocket.rs +++ b/net-guardia/src/web/utils/flow_websocket.rs @@ -0,0 +1,34 @@ +use actix::prelude::*; +use actix_web_actors::ws; + +pub struct IPv4FlowWebSocket { + pub interval: Option, +} + +impl Actor for IPv4FlowWebSocket { + type Context = ws::WebsocketContext; + + fn started(&mut self, ctx: &mut Self::Context) { + + } + + fn stopping(&mut self, ctx: &mut Self::Context) -> Running { + Running::Stop + } +} + +pub struct IPv6FlowWebSocket { + pub interval: Option, +} + +impl Actor for IPv6FlowWebSocket { + type Context = ws::WebsocketContext; + + fn started(&mut self, ctx: &mut Self::Context) { + + } + + fn stopping(&mut self, ctx: &mut Self::Context) -> Running { + Running::Stop + } +} \ No newline at end of file diff --git a/net-guardia/src/web/utils/map_util.rs b/net-guardia/src/web/utils/map_util.rs new file mode 100644 index 0000000..07ee00f --- /dev/null +++ b/net-guardia/src/web/utils/map_util.rs @@ -0,0 +1,25 @@ +use crate::model::flow_stats::FlowStats; +use net_guardia_common::model::flow_stats::FlowStats as EbpfFlowStats; +use net_guardia_common::model::ip_address::{ + AddrPortV4 as EbpfAddrPortV4, AddrPortV6 as EbpfAddrPortV6, +}; +use std::collections::HashMap; +use crate::utils::definition::IntoString; + +pub fn transform_ipv4_flow_data( + original: HashMap, +) -> HashMap { + original + .into_iter() + .map(|(key, value)| (key.into_string(), FlowStats::from(value))) + .collect() +} + +pub fn transform_ipv6_flow_data( + original: HashMap, +) -> HashMap { + original + .into_iter() + .map(|(key, value)| (key.into_string(), FlowStats::from(value))) + .collect() +} diff --git a/net-guardia/src/web/utils/mod.rs b/net-guardia/src/web/utils/mod.rs index d7dc8fb..d751bb0 100644 --- a/net-guardia/src/web/utils/mod.rs +++ b/net-guardia/src/web/utils/mod.rs @@ -1 +1,2 @@ -pub mod flow_websocket; \ No newline at end of file +pub mod flow_websocket; +pub mod map_util; \ No newline at end of file