use crate::common::NetStatRow;
use std::collections::HashMap;
use std::io::{BufRead, Error, Read};
pub fn parse_netstat_output(output: &str) -> Vec<NetStatRow> {
output
.lines()
.skip(2) .filter_map(|line| {
let parts: Vec<&str> = line.split_whitespace().collect();
if parts.len() == 17 {
let name = parts[0].to_string();
let name = if name.ends_with(":") {
name[..name.len() - 1].to_string()
} else {
name
};
let ipkts = parts[2].parse().unwrap_or(0);
let ierrs = parts[3].parse().unwrap_or(0);
let ibytes = parts[1].parse().unwrap_or(0);
let opkts = parts[10].parse().unwrap_or(0);
let oerrs = parts[11].parse().unwrap_or(0);
let obytes = parts[9].parse().unwrap_or(0);
let colls = parts[14].parse().unwrap_or(0);
let drop = parts[4].parse().unwrap_or(0);
let mtu = parts[2].parse().unwrap_or(0);
Some(NetStatRow {
name,
ipkts,
opkts,
ibytes,
obytes,
ierrs,
oerrs,
drop,
colls,
mtu,
})
} else {
None
}
})
.collect() }
fn parse_netstat_table(content: &str) -> HashMap<String, u64> {
let mut map = HashMap::new();
for line in content.lines().skip(1) {
let parts: Vec<&str> = line.split_whitespace().collect();
if parts.len() != 11 {
continue;
}
let name = parts[0].to_string();
let mtu = parts[1].parse().unwrap_or(0);
map.insert(name, mtu);
}
map
}
pub fn get_current_netstat() -> Result<Vec<NetStatRow>, Error> {
let output = std::process::Command::new("netstat")
.arg("-i")
.output()
.expect("failed to execute process");
let output_str = String::from_utf8(output.stdout).unwrap();
let iface_mtu_map = parse_netstat_table(&output_str);
let content = std::fs::read_to_string("/proc/net/dev")?;
let mut stats = parse_netstat_output(&content);
for stat in stats.iter_mut() {
if let Some(mtu) = iface_mtu_map.get(&stat.name) {
stat.mtu = *mtu;
}
}
Ok(stats)
}