179 lines
4.5 KiB
Rust
179 lines
4.5 KiB
Rust
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<u32>,
|
|
pub is_up: Option<bool>,
|
|
pub mtu: Option<u32>,
|
|
pub mac: Option<String>,
|
|
pub addresses: Vec<NetAddress>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct NetAddress {
|
|
pub ip: String,
|
|
pub prefix_len: Option<u8>,
|
|
pub scope: Option<String>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct DnsConfigSnapshot {
|
|
pub servers: Vec<String>,
|
|
pub search_domains: Vec<String>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct RouteEntry {
|
|
pub destination: String,
|
|
pub gateway: Option<String>,
|
|
pub interface: Option<String>,
|
|
pub metric: Option<u32>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct ListenSocket {
|
|
pub proto: String,
|
|
pub local_addr: String,
|
|
pub state: Option<String>,
|
|
pub pid: Option<u32>,
|
|
pub ppid: Option<u32>,
|
|
pub process_name: Option<String>,
|
|
pub process_path: Option<String>,
|
|
pub owner: Option<String>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct ConnSocket {
|
|
pub proto: String,
|
|
pub local_addr: String,
|
|
pub remote_addr: String,
|
|
pub state: Option<String>,
|
|
pub pid: Option<u32>,
|
|
pub ppid: Option<u32>,
|
|
pub process_name: Option<String>,
|
|
pub process_path: Option<String>,
|
|
}
|
|
|
|
#[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<u32>,
|
|
pub store: Option<String>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct NeighborEntry {
|
|
pub ip: String,
|
|
pub mac: Option<String>,
|
|
pub interface: Option<String>,
|
|
pub state: Option<String>,
|
|
}
|
|
|
|
#[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<u32>,
|
|
pub ppid: Option<u32>,
|
|
pub process_name: Option<String>,
|
|
pub process_path: Option<String>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct FlowOwnerResult {
|
|
pub owner: Option<FlowOwner>,
|
|
pub confidence: FlowOwnerConfidence,
|
|
pub failure_reason: Option<String>,
|
|
}
|
|
|
|
#[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<String>) -> Self {
|
|
Self {
|
|
code,
|
|
message: message.into(),
|
|
}
|
|
}
|
|
|
|
pub fn not_supported(message: impl Into<String>) -> Self {
|
|
Self::new(ErrorCode::NotSupported, message)
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
pub trait SysProvider: Send + Sync {
|
|
async fn interfaces(&self) -> Result<Vec<NetInterface>, PlatformError>;
|
|
async fn routes(&self) -> Result<Vec<RouteEntry>, PlatformError>;
|
|
async fn dns_config(&self) -> Result<DnsConfigSnapshot, PlatformError>;
|
|
}
|
|
|
|
#[async_trait]
|
|
pub trait PortsProvider: Send + Sync {
|
|
async fn listening(&self) -> Result<Vec<ListenSocket>, PlatformError>;
|
|
async fn who_owns(&self, port: u16) -> Result<Vec<ListenSocket>, PlatformError>;
|
|
async fn connections(&self) -> Result<Vec<ConnSocket>, PlatformError>;
|
|
}
|
|
|
|
#[async_trait]
|
|
pub trait CertProvider: Send + Sync {
|
|
async fn trusted_roots(&self) -> Result<Vec<RootCert>, PlatformError>;
|
|
}
|
|
|
|
#[async_trait]
|
|
pub trait NeighProvider: Send + Sync {
|
|
async fn neighbors(&self) -> Result<Vec<NeighborEntry>, PlatformError>;
|
|
}
|
|
|
|
#[async_trait]
|
|
pub trait FlowOwnerProvider: Send + Sync {
|
|
async fn owner_of(&self, flow: FlowTuple) -> Result<FlowOwnerResult, PlatformError>;
|
|
}
|
|
|
|
pub struct Platform {
|
|
pub sys: Arc<dyn SysProvider>,
|
|
pub ports: Arc<dyn PortsProvider>,
|
|
pub cert: Arc<dyn CertProvider>,
|
|
pub neigh: Arc<dyn NeighProvider>,
|
|
pub flow_owner: Arc<dyn FlowOwnerProvider>,
|
|
}
|