nd_300/diagnostics/
mtu.rs1use serde::Serialize;
2
3#[derive(Debug, Clone, Serialize)]
4pub struct MtuInfo {
5 pub interface: String,
6 pub mtu: u32,
7}
8
9pub async fn collect() -> Option<Vec<MtuInfo>> {
10 let mut results = Vec::new();
11
12 #[cfg(windows)]
13 {
14 let mut cmd = tokio::process::Command::new("netsh");
15 cmd.args(["interface", "ipv4", "show", "subinterfaces"]);
16 if let Some(output) = super::util::run_with_timeout(cmd, super::util::QUICK).await {
17 let text = String::from_utf8_lossy(&output.stdout);
18 for line in text.lines() {
19 let parts: Vec<&str> = line.split_whitespace().collect();
20 if parts.len() >= 5 {
22 if let Ok(mtu) = parts[0].parse::<u32>() {
23 let iface = parts[4..].join(" ");
24 results.push(MtuInfo {
25 interface: iface,
26 mtu,
27 });
28 }
29 }
30 }
31 }
32 }
33
34 #[cfg(target_os = "linux")]
35 {
36 let mut cmd = tokio::process::Command::new("ip");
37 cmd.args(["link", "show"]);
38 if let Some(output) = super::util::run_with_timeout(cmd, super::util::QUICK).await {
39 let text = String::from_utf8_lossy(&output.stdout);
40 for line in text.lines() {
41 if line.contains("mtu") {
42 let parts: Vec<&str> = line.split_whitespace().collect();
43 if let Some(name_idx) = parts
44 .iter()
45 .position(|p| p.ends_with(':') && !p.starts_with(' '))
46 {
47 let name = parts[name_idx].trim_end_matches(':');
48 if let Some(mtu_idx) = parts.iter().position(|p| *p == "mtu") {
49 if let Some(mtu_val) = parts.get(mtu_idx + 1) {
50 if let Ok(mtu) = mtu_val.parse::<u32>() {
51 results.push(MtuInfo {
52 interface: name.to_string(),
53 mtu,
54 });
55 }
56 }
57 }
58 }
59 }
60 }
61 }
62 }
63
64 #[cfg(target_os = "macos")]
65 {
66 let cmd = tokio::process::Command::new("ifconfig");
67 if let Some(output) = super::util::run_with_timeout(cmd, super::util::QUICK).await {
68 let text = String::from_utf8_lossy(&output.stdout);
69 let mut current_iface = String::new();
70
71 for line in text.lines() {
72 if !line.starts_with('\t') && !line.starts_with(' ') {
73 current_iface = line.split(':').next().unwrap_or("").to_string();
74 }
75 if line.contains("mtu") {
76 let parts: Vec<&str> = line.split_whitespace().collect();
77 if let Some(mtu_idx) = parts.iter().position(|p| *p == "mtu") {
78 if let Some(mtu_val) = parts.get(mtu_idx + 1) {
79 if let Ok(mtu) = mtu_val.parse::<u32>() {
80 results.push(MtuInfo {
81 interface: current_iface.clone(),
82 mtu,
83 });
84 }
85 }
86 }
87 }
88 }
89 }
90 }
91
92 if results.is_empty() {
93 None
94 } else {
95 Some(results)
96 }
97}