From 286f0d4099a2472d45c91cfe7a028ccb9f8a85a7 Mon Sep 17 00:00:00 2001 From: Christian Ebner Date: Mon, 15 Apr 2019 10:48:43 +0200 Subject: [PATCH] src/tools/procfs.rs: implement read_proc_net_route() Signed-off-by: Christian Ebner --- src/tools/procfs.rs | 66 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/tools/procfs.rs b/src/tools/procfs.rs index f1f09637..ab855e31 100644 --- a/src/tools/procfs.rs +++ b/src/tools/procfs.rs @@ -4,6 +4,7 @@ use std::fs::OpenOptions; use std::io::{BufRead, BufReader}; use std::collections::HashSet; use std::process; +use std::net::Ipv4Addr; use crate::tools; use lazy_static::lazy_static; use regex::Regex; @@ -263,3 +264,68 @@ pub fn read_proc_net_dev() -> Result, Error> { Ok(result) } + +fn hex_nibble(c: u8) -> Result { + 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>(hex: T) -> Result { + 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, 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) +}