-
Notifications
You must be signed in to change notification settings - Fork 0
/
models.rs
147 lines (133 loc) · 4.02 KB
/
models.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
use std::fmt::{Display, Formatter};
use std::net::IpAddr;
use std::str::FromStr;
use chrono::{DateTime, Utc};
use seahash::hash;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Traceroute {
/// Platform-specific measurement description
pub measurement_name: String,
/// Platform-specific measurement identifier:
/// `msm_id` on Atlas, `cycle_id` on Scamper / Ark, `measurement_uuid` on Iris, etc.
/// The precise semantics of this field depends on the platform. In general, assume that a same
/// measurement identifier might be used by multiple traceroutes from multiple vantage points
/// towards multiple destinations.
pub measurement_id: String,
/// Platform-specific vantage point identifier.
pub agent_id: String,
pub start_time: DateTime<Utc>,
pub end_time: DateTime<Utc>,
pub protocol: Protocol,
pub src_addr: IpAddr,
pub src_addr_public: Option<IpAddr>,
pub dst_addr: IpAddr,
pub flows: Vec<TracerouteFlow>,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct TracerouteFlow {
// TODO: Store detailed flow ID information instead of src/dst port.
// pub enum FlowId {
// ICMPChecksum(u16),
// TCPSourcePort(u16),
// UDPSourcePort(u16),
// }
// pub id: FlowId,
pub src_port: u16,
pub dst_port: u16,
// TODO: HashMap instead?
pub hops: Vec<TracerouteHop>,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct TracerouteHop {
pub ttl: u8,
pub probes: Vec<TracerouteProbe>,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct TracerouteProbe {
pub timestamp: DateTime<Utc>,
pub size: u16,
pub reply: Option<TracerouteReply>,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct TracerouteReply {
pub timestamp: DateTime<Utc>,
pub quoted_ttl: u8,
pub ttl: u8,
pub size: u16,
pub addr: IpAddr,
pub icmp_type: u8,
pub icmp_code: u8,
pub mpls_labels: Vec<MplsEntry>,
pub rtt: f64,
}
impl Traceroute {
pub fn af(&self) -> u8 {
if self.dst_addr.is_ipv4() {
4
} else {
6
}
}
// Not all platform use an integer agent id.
// Our strategy is to first try to parse the id as an int, and fall back on the hash otherwise.
pub fn agent_id_int(&self) -> u64 {
self.agent_id
.parse()
.unwrap_or_else(|_| hash(self.agent_id.as_bytes()))
}
// See `agent_id_int`.
pub fn measurement_id_int(&self) -> u64 {
self.measurement_id
.parse()
.unwrap_or_else(|_| hash(self.measurement_id.as_bytes()))
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct MplsEntry {
pub label: u32,
pub exp: u8,
pub bottom_of_stack: u8,
pub ttl: u8,
}
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum Protocol {
ICMP,
ICMPv6,
TCP,
UDP,
}
impl Display for Protocol {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Protocol::ICMP => write!(f, "ICMP"),
Protocol::ICMPv6 => write!(f, "ICMP6"),
Protocol::TCP => write!(f, "TCP"),
Protocol::UDP => write!(f, "UDP"),
}
}
}
impl FromStr for Protocol {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"ICMP" => Ok(Protocol::ICMP),
"ICMP6" => Ok(Protocol::ICMP),
"TCP" => Ok(Protocol::TCP),
"UDP" => Ok(Protocol::UDP),
_ => Err(format!("Unsupported protocol: {s}")),
}
}
}
impl TryFrom<u8> for Protocol {
type Error = String;
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
1 => Ok(Protocol::ICMP),
6 => Ok(Protocol::TCP),
17 => Ok(Protocol::UDP),
58 => Ok(Protocol::ICMPv6),
_ => Err(format!("Unsupported protocol: {value}")),
}
}
}