use crate::tracing::types::{Round, Sequence, TimeToLive};
use std::net::IpAddr;
use std::time::{Duration, SystemTime};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct Probe {
pub sequence: Sequence,
pub ttl: TimeToLive,
pub round: Round,
pub sent: Option<SystemTime>,
pub status: ProbeStatus,
pub host: Option<IpAddr>,
pub received: Option<SystemTime>,
pub icmp_packet_type: Option<IcmpPacketType>,
}
impl Probe {
#[must_use]
pub const fn new(sequence: Sequence, ttl: TimeToLive, round: Round, sent: SystemTime) -> Self {
Self {
sequence,
ttl,
round,
sent: Some(sent),
status: ProbeStatus::Awaited,
host: None,
received: None,
icmp_packet_type: None,
}
}
#[must_use]
pub fn duration(&self) -> Duration {
match (self.sent, self.received) {
(Some(sent), Some(recv)) => recv.duration_since(sent).unwrap_or_default(),
(Some(sent), None) => sent.elapsed().unwrap_or_default(),
_ => Duration::default(),
}
}
#[must_use]
pub const fn with_status(self, status: ProbeStatus) -> Self {
Self { status, ..self }
}
#[must_use]
pub const fn with_icmp_packet_type(self, icmp_packet_type: IcmpPacketType) -> Self {
Self {
icmp_packet_type: Some(icmp_packet_type),
..self
}
}
#[must_use]
pub const fn with_host(self, host: IpAddr) -> Self {
Self {
host: Some(host),
..self
}
}
#[must_use]
pub const fn with_received(self, received: SystemTime) -> Self {
Self {
received: Some(received),
..self
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ProbeStatus {
NotSent,
Awaited,
Complete,
}
impl Default for ProbeStatus {
fn default() -> Self {
Self::NotSent
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum IcmpPacketType {
TimeExceeded,
EchoReply,
Unreachable,
NotApplicable,
}
#[derive(Debug, Copy, Clone)]
pub enum ProbeResponse {
TimeExceeded(ProbeResponseData),
DestinationUnreachable(ProbeResponseData),
EchoReply(ProbeResponseData),
TcpReply(TcpProbeResponseData),
TcpRefused(TcpProbeResponseData),
}
#[derive(Debug, Copy, Clone)]
pub struct ProbeResponseData {
pub recv: SystemTime,
pub addr: IpAddr,
pub identifier: u16,
pub sequence: u16,
}
impl ProbeResponseData {
pub fn new(recv: SystemTime, addr: IpAddr, identifier: u16, sequence: u16) -> Self {
Self {
recv,
addr,
identifier,
sequence,
}
}
}
#[derive(Debug, Copy, Clone)]
pub struct TcpProbeResponseData {
pub recv: SystemTime,
pub addr: IpAddr,
pub ttl: u8,
}
impl TcpProbeResponseData {
pub fn new(recv: SystemTime, addr: IpAddr, ttl: u8) -> Self {
Self { recv, addr, ttl }
}
}