use async_trait::async_trait; use serde::{Deserialize, Serialize}; use std::net::IpAddr; use std::sync::Arc; use wtfnet_core::ErrorCode; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct NetInterface { pub name: String, pub index: Option, pub is_up: Option, pub mtu: Option, pub mac: Option, pub addresses: Vec, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct NetAddress { pub ip: String, pub prefix_len: Option, pub scope: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct DnsConfigSnapshot { pub servers: Vec, pub search_domains: Vec, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct RouteEntry { pub destination: String, pub gateway: Option, pub interface: Option, pub metric: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ListenSocket { pub proto: String, pub local_addr: String, pub state: Option, pub pid: Option, pub ppid: Option, pub process_name: Option, pub process_path: Option, pub owner: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ConnSocket { pub proto: String, pub local_addr: String, pub remote_addr: String, pub state: Option, pub pid: Option, pub ppid: Option, pub process_name: Option, pub process_path: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct RootCert { pub subject: String, pub issuer: String, pub not_before: String, pub not_after: String, pub serial_number: String, pub sha1: String, pub sha256: String, pub key_algorithm: String, pub key_size: Option, pub store: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct NeighborEntry { pub ip: String, pub mac: Option, pub interface: Option, pub state: Option, } #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "lowercase")] pub enum FlowProtocol { Udp, Tcp, } #[derive(Debug, Clone, Copy, Serialize, Deserialize)] #[serde(rename_all = "lowercase")] pub enum FlowOwnerConfidence { High, Medium, Low, None, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct FlowOwner { pub pid: Option, pub ppid: Option, pub process_name: Option, pub process_path: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct FlowOwnerResult { pub owner: Option, pub confidence: FlowOwnerConfidence, pub failure_reason: Option, } #[derive(Debug, Clone)] pub struct FlowTuple { pub proto: FlowProtocol, pub src_ip: IpAddr, pub src_port: u16, pub dst_ip: IpAddr, pub dst_port: u16, } #[derive(Debug, Clone)] pub struct PlatformError { pub code: ErrorCode, pub message: String, } impl PlatformError { pub fn new(code: ErrorCode, message: impl Into) -> Self { Self { code, message: message.into(), } } pub fn not_supported(message: impl Into) -> Self { Self::new(ErrorCode::NotSupported, message) } } #[async_trait] pub trait SysProvider: Send + Sync { async fn interfaces(&self) -> Result, PlatformError>; async fn routes(&self) -> Result, PlatformError>; async fn dns_config(&self) -> Result; } #[async_trait] pub trait PortsProvider: Send + Sync { async fn listening(&self) -> Result, PlatformError>; async fn who_owns(&self, port: u16) -> Result, PlatformError>; async fn connections(&self) -> Result, PlatformError>; } #[async_trait] pub trait CertProvider: Send + Sync { async fn trusted_roots(&self) -> Result, PlatformError>; } #[async_trait] pub trait NeighProvider: Send + Sync { async fn neighbors(&self) -> Result, PlatformError>; } #[async_trait] pub trait FlowOwnerProvider: Send + Sync { async fn owner_of(&self, flow: FlowTuple) -> Result; } pub struct Platform { pub sys: Arc, pub ports: Arc, pub cert: Arc, pub neigh: Arc, pub flow_owner: Arc, }