src/tools/procfs.rs: implement read_proc_net_route()
Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
This commit is contained in:
parent
1a6c9415ae
commit
286f0d4099
|
@ -4,6 +4,7 @@ use std::fs::OpenOptions;
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::process;
|
use std::process;
|
||||||
|
use std::net::Ipv4Addr;
|
||||||
use crate::tools;
|
use crate::tools;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
@ -263,3 +264,68 @@ pub fn read_proc_net_dev() -> Result<Vec<ProcFsNetDev>, Error> {
|
||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn hex_nibble(c: u8) -> Result<u8, Error> {
|
||||||
|
Ok(match c {
|
||||||
|
b'0'..=b'9' => c - b'0',
|
||||||
|
b'a'..=b'f' => c - b'a' + 0xa,
|
||||||
|
b'A'..=b'F' => c - b'A' + 0xa,
|
||||||
|
_ => bail!("not a hex digit: {}", c as char),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hexstr_to_ipv4addr<T: AsRef<[u8]>>(hex: T) -> Result<Ipv4Addr, Error> {
|
||||||
|
let hex = hex.as_ref();
|
||||||
|
if hex.len() != 8 {
|
||||||
|
bail!("Error while converting hex string to IP address: unexpected string length");
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut addr: [u8; 4] = unsafe { std::mem::uninitialized() };
|
||||||
|
for i in 0..4 {
|
||||||
|
addr[3 - i] = (hex_nibble(hex[i * 2])? << 4) + hex_nibble(hex[i * 2 + 1])?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Ipv4Addr::from(addr))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ProcFsNetRoute {
|
||||||
|
pub dest: Ipv4Addr,
|
||||||
|
pub gateway: Ipv4Addr,
|
||||||
|
pub mask: Ipv4Addr,
|
||||||
|
pub metric: u32,
|
||||||
|
pub mtu: u32,
|
||||||
|
pub iface: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_proc_net_route() -> Result<Vec<ProcFsNetRoute>, Error> {
|
||||||
|
let path = "/proc/net/route";
|
||||||
|
let file = OpenOptions::new().read(true).open(&path)?;
|
||||||
|
let err = "Error while parsing '/proc/net/route";
|
||||||
|
|
||||||
|
let mut result = Vec::new();
|
||||||
|
for line in BufReader::new(&file).lines().skip(1) {
|
||||||
|
let content = line?;
|
||||||
|
if content.is_empty() { continue; }
|
||||||
|
let mut iter = content.split_whitespace();
|
||||||
|
|
||||||
|
let iface = iter.next().ok_or(format_err!("{}", err))?;
|
||||||
|
let dest = iter.next().ok_or(format_err!("{}", err))?;
|
||||||
|
let gateway = iter.next().ok_or(format_err!("{}", err))?;
|
||||||
|
for _ in 0..3 { iter.next(); }
|
||||||
|
let metric = iter.next().ok_or(format_err!("{}", err))?;
|
||||||
|
let mask = iter.next().ok_or(format_err!("{}", err))?;
|
||||||
|
let mtu = iter.next().ok_or(format_err!("{}", err))?;
|
||||||
|
|
||||||
|
result.push(ProcFsNetRoute {
|
||||||
|
dest: hexstr_to_ipv4addr(dest)?,
|
||||||
|
gateway: hexstr_to_ipv4addr(gateway)?,
|
||||||
|
mask: hexstr_to_ipv4addr(mask)?,
|
||||||
|
metric: metric.parse()?,
|
||||||
|
mtu: mtu.parse()?,
|
||||||
|
iface: iface.to_string(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue