use serde::{Deserialize, Serialize};
use std::collections::HashMap;
pub const ENRICHMENT_VERSION: u32 = 1;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct IntelEnrichment {
pub version: u32,
pub source: String,
pub target_type: String,
pub target_value: String,
pub classification: Option<String>,
pub asn: Option<AsnInfo>,
pub geo: Option<GeoInfo>,
pub services: Vec<ServiceInfo>,
pub technologies: Vec<String>,
pub passive_dns: Vec<DnsRecord>,
pub tags: Vec<String>,
pub raw: HashMap<String, serde_json::Value>,
pub fetched_at: u64,
}
impl IntelEnrichment {
pub fn new(
source: impl Into<String>,
target_type: impl Into<String>,
target_value: impl Into<String>,
) -> Self {
Self {
version: ENRICHMENT_VERSION,
source: source.into(),
target_type: target_type.into(),
target_value: target_value.into(),
classification: None,
asn: None,
geo: None,
services: Vec::new(),
technologies: Vec::new(),
passive_dns: Vec::new(),
tags: Vec::new(),
raw: HashMap::new(),
fetched_at: now(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct AsnInfo {
pub asn: String,
pub org: Option<String>,
pub domain: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct GeoInfo {
pub country: Option<String>,
pub city: Option<String>,
pub region: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ServiceInfo {
pub port: u16,
pub protocol: String,
pub banner: Option<String>,
pub product: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct DnsRecord {
pub record_type: String,
pub value: String,
pub first_seen: Option<String>,
pub last_seen: Option<String>,
}
fn now() -> u64 {
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap_or_default()
.as_secs()
}