1use std::time::Duration;
8
9use serde::{Deserialize, Serialize};
10
11use crate::connection::ConnectionId;
12use crate::dns::DnsResolution;
13use crate::link::{L4Proto, Link, Neighbor, Route};
14use crate::path::ProbeResults;
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
19#[serde(rename_all = "snake_case")]
20pub enum Layer {
21 Link,
22 Address,
23 Gateway,
24 Dns,
25 Internet,
26 Firewall,
27 Service,
28}
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
32#[serde(rename_all = "snake_case")]
33pub enum Severity {
34 Info,
36 Warn,
38 Broken,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize)]
44pub struct Finding {
45 pub layer: Layer,
46 pub severity: Severity,
47 pub summary: String,
49 pub detail: Option<String>,
51 pub remedy: Option<Remedy>,
52 pub evidence: Evidence,
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize)]
57#[serde(tag = "type", rename_all = "snake_case")]
58pub enum Remedy {
59 Run { cmd: String },
61 Check { what: String },
63 Reconnect { id: ConnectionId },
65 ElevatePrivileges,
67 None,
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize)]
75#[serde(tag = "type", rename_all = "snake_case")]
76pub enum Evidence {
77 Link { link: Link },
78 Neighbor { neighbor: Neighbor },
79 Route { route: Route },
80 Dns { dns: DnsResolution },
81 Probe { probe: Box<ProbeResults> },
82 Text { text: String },
83}
84
85#[derive(Debug, Clone, Serialize, Deserialize)]
87#[serde(tag = "type", rename_all = "snake_case")]
88pub enum Health {
89 Ok,
90 Degraded { findings: Vec<Finding> },
91 Broken { findings: Vec<Finding> },
92}
93
94#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
96#[serde(rename_all = "snake_case")]
97pub enum CheckScope {
98 Quick,
100 Full,
103}
104
105#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
107#[serde(rename_all = "snake_case")]
108pub enum FirewallVerdict {
109 Allow,
110 Drop,
111 Reject,
112 NoMatch,
115 Unknown,
116}
117
118#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
120#[serde(rename_all = "snake_case")]
121pub enum FirewallBackend {
122 Nftables,
124 Iptables,
126 Unknown,
128}
129
130#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
132pub struct ProbeCapabilities {
133 pub has_ping: bool,
134 pub has_traceroute: bool,
135 pub has_mtr: bool,
136 pub has_tracepath: bool,
137 pub unprivileged_icmp: bool,
140}
141
142#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
144pub struct PingOpts {
145 pub count: u32,
147 pub timeout: Duration,
149}
150
151impl Default for PingOpts {
152 fn default() -> Self {
153 Self {
154 count: 2,
155 timeout: Duration::from_secs(1),
156 }
157 }
158}
159
160#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
162pub struct TraceOpts {
163 pub max_hops: u8,
165 pub timeout_per_hop: Duration,
167 pub proto: L4Proto,
169}
170
171impl Default for TraceOpts {
172 fn default() -> Self {
173 Self {
174 max_hops: 20,
175 timeout_per_hop: Duration::from_secs(1),
176 proto: L4Proto::Udp,
177 }
178 }
179}