57b5fd6b77
- Scan ping TCP multi-ports (sans root requis) - Lecture table ARP Linux (/proc/net/arp) - Détection 20 services par scan de ports TCP - Base OUI embarquée (~70 constructeurs courants) - API JSON locale Axum sur :9100 (GET /devices, GET /health) - Push automatique vers backend /api/v1/network - Enregistrement agent au démarrage - Config YAML (subnet 10.0.0.0/22, concurrence, timeouts) - ROADMAP Phase 1 et 2 marquées complètes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
62 lines
1.6 KiB
Rust
62 lines
1.6 KiB
Rust
use serde::{Deserialize, Serialize};
|
|
|
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
|
pub struct Config {
|
|
pub backend: BackendConfig,
|
|
pub agent: AgentConfig,
|
|
pub scan: ScanConfig,
|
|
pub api: ApiConfig,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
|
pub struct BackendConfig {
|
|
pub url: String,
|
|
pub token: String,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
|
pub struct AgentConfig {
|
|
pub id: String,
|
|
pub hostname: String,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
|
pub struct ScanConfig {
|
|
pub subnets: Vec<String>,
|
|
pub interval_seconds: u64,
|
|
pub ping_timeout_ms: u64,
|
|
pub service_timeout_ms: u64,
|
|
pub concurrency: usize,
|
|
pub ports: Vec<u16>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
|
pub struct ApiConfig {
|
|
pub listen: String,
|
|
}
|
|
|
|
impl Config {
|
|
pub fn load(path: &str) -> anyhow::Result<Self> {
|
|
let content = std::fs::read_to_string(path)?;
|
|
let mut cfg: Config = serde_yaml::from_str(&content)?;
|
|
cfg.resolve_defaults();
|
|
Ok(cfg)
|
|
}
|
|
|
|
fn resolve_defaults(&mut self) {
|
|
if self.agent.hostname.is_empty() {
|
|
self.agent.hostname = detect_hostname();
|
|
}
|
|
if self.agent.id.is_empty() {
|
|
self.agent.id = format!("scan-{}", self.agent.hostname);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn detect_hostname() -> String {
|
|
// Lecture directe de /etc/hostname (Linux)
|
|
std::fs::read_to_string("/etc/hostname")
|
|
.map(|s| s.trim().to_string())
|
|
.unwrap_or_else(|_| "unknown".into())
|
|
}
|