use serde::Deserialize;
use std::net::IpAddr;
use trippy_core::Port;
#[derive(Debug, Deserialize)]
pub struct Simulation {
pub name: String,
pub rounds: Option<usize>,
#[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<u16>,
pub packet_size: Option<u16>,
pub payload_pattern: Option<u8>,
pub tos: Option<u8>,
pub min_round_duration: Option<u64>,
pub max_round_duration: Option<u64>,
pub grace_duration: Option<u64>,
pub hops: Vec<Hop>,
}
impl Simulation {
pub fn latest_ttl(&self) -> u8 {
if self.hops.is_empty() {
0
} else {
self.hops[self.hops.len() - 1].ttl
}
}
}
#[derive(Debug, Deserialize)]
pub struct Hop {
pub ttl: u8,
pub resp: Response,
}
#[derive(Debug, Deserialize)]
#[serde(tag = "tag")]
pub enum Response {
NoResponse,
SingleHost(SingleHost),
}
#[derive(Debug, Deserialize)]
pub struct SingleHost {
pub addr: IpAddr,
pub rtt_ms: u16,
}
#[derive(Copy, Clone, Debug, Default, Deserialize)]
pub enum PrivilegeMode {
#[default]
Privileged,
Unprivileged,
}
impl From<PrivilegeMode> 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<Protocol> 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)]
#[serde(tag = "tag", content = "value")]
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<PortDirection> 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<MultipathStrategy> for trippy_core::MultipathStrategy {
fn from(value: MultipathStrategy) -> Self {
match value {
MultipathStrategy::Classic => Self::Classic,
MultipathStrategy::Paris => Self::Paris,
MultipathStrategy::Dublin => Self::Dublin,
}
}
}