use serde::Deserialize; use std::net::IpAddr; use trippy_core::Port; /// A simulated trace. #[derive(Debug, Deserialize)] pub struct Simulation { pub name: String, pub rounds: Option, #[serde(default)] pub privilege_mode: PrivilegeMode, pub target: IpAddr, pub protocol: Protocol, #[serde(default)] pub port_direction: PortDirection, #[serde(default)] pub multipath_strategy: MultipathStrategy, #[serde(default)] pub icmp_identifier: u16, pub initial_sequence: Option, pub packet_size: Option, pub payload_pattern: Option, pub min_round_duration: Option, pub max_round_duration: Option, pub grace_duration: Option, pub hops: Vec, } impl Simulation { pub fn latest_ttl(&self) -> u8 { if self.hops.is_empty() { 0 } else { self.hops[self.hops.len() - 1].ttl } } } /// A simulated hop. #[derive(Debug, Deserialize)] pub struct Hop { /// The simulated time-to-live (TTL). pub ttl: u8, /// The simulated probe response. pub resp: Response, } /// A simulated probe response. #[derive(Debug, Deserialize)] pub enum Response { /// Simulate a hop which does not response to probes. NoResponse, /// Simulate a hop which responds to probes from a single host. SingleHost(SingleHost), } /// A simulated probe response with a single addr and fixed ttl. #[derive(Debug, Deserialize)] pub struct SingleHost { /// The simulated host responding to the probe. pub addr: IpAddr, /// The simulated round trim time (RTT) in ms. pub rtt_ms: u16, } #[derive(Copy, Clone, Debug, Default, Deserialize)] pub enum PrivilegeMode { #[default] Privileged, Unprivileged, } impl From for trippy_core::PrivilegeMode { fn from(value: PrivilegeMode) -> Self { match value { PrivilegeMode::Privileged => Self::Privileged, PrivilegeMode::Unprivileged => Self::Unprivileged, } } } #[derive(Copy, Clone, Debug, Deserialize)] pub enum Protocol { Icmp, Udp, Tcp, } impl From for trippy_core::Protocol { fn from(value: Protocol) -> Self { match value { Protocol::Icmp => Self::Icmp, Protocol::Udp => Self::Udp, Protocol::Tcp => Self::Tcp, } } } #[derive(Copy, Clone, Debug, Default, Deserialize)] pub enum PortDirection { #[default] None, FixedSrc(u16), FixedDest(u16), FixedBoth(FixedBoth), } #[derive(Copy, Clone, Debug, Default, Deserialize)] pub struct FixedBoth { pub src: u16, pub dest: u16, } impl From for trippy_core::PortDirection { fn from(value: PortDirection) -> Self { match value { PortDirection::None => Self::None, PortDirection::FixedSrc(src) => Self::FixedSrc(Port(src)), PortDirection::FixedDest(dest) => Self::FixedDest(Port(dest)), PortDirection::FixedBoth(FixedBoth { src, dest }) => { Self::FixedBoth(Port(src), Port(dest)) } } } } #[derive(Copy, Clone, Debug, Default, Deserialize)] pub enum MultipathStrategy { #[default] Classic, Paris, Dublin, } impl From for trippy_core::MultipathStrategy { fn from(value: MultipathStrategy) -> Self { match value { MultipathStrategy::Classic => Self::Classic, MultipathStrategy::Paris => Self::Paris, MultipathStrategy::Dublin => Self::Dublin, } } }