src/tools/procfs.rs: implement read_proc_net_ipv6_route()
Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
This commit is contained in:
parent
8c3c63fad0
commit
eb46c3d1ec
|
@ -1,10 +1,11 @@
|
|||
use failure::*;
|
||||
|
||||
use std::u32;
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::collections::HashSet;
|
||||
use std::process;
|
||||
use std::net::Ipv4Addr;
|
||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||
use crate::tools;
|
||||
use lazy_static::lazy_static;
|
||||
use regex::Regex;
|
||||
|
@ -277,7 +278,7 @@ fn hex_nibble(c: u8) -> Result<u8, Error> {
|
|||
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");
|
||||
bail!("Error while converting hex string to IPv4 address: unexpected string length");
|
||||
}
|
||||
|
||||
let mut addr: [u8; 4] = unsafe { std::mem::uninitialized() };
|
||||
|
@ -329,3 +330,80 @@ pub fn read_proc_net_route() -> Result<Vec<ProcFsNetRoute>, Error> {
|
|||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn hexstr_to_ipv6addr<T: AsRef<[u8]>>(hex: T) -> Result<Ipv6Addr, Error> {
|
||||
let hex = hex.as_ref();
|
||||
if hex.len() != 32 {
|
||||
bail!("Error while converting hex string to IPv6 address: unexpected string length");
|
||||
}
|
||||
|
||||
let mut addr: [u8; 16] = unsafe { std::mem::uninitialized() };
|
||||
for i in 0..16 {
|
||||
addr[i] = (hex_nibble(hex[i * 2])? << 4) + hex_nibble(hex[i * 2 + 1])?;
|
||||
}
|
||||
|
||||
Ok(Ipv6Addr::from(addr))
|
||||
}
|
||||
|
||||
fn hexstr_to_u8<T: AsRef<[u8]>>(hex: T) -> Result<u8, Error> {
|
||||
let hex = hex.as_ref();
|
||||
if hex.len() != 2 {
|
||||
bail!("Error while converting hex string to u8: unexpected string length");
|
||||
}
|
||||
|
||||
Ok((hex_nibble(hex[0])? << 4) + hex_nibble(hex[1])?)
|
||||
}
|
||||
|
||||
fn hexstr_to_u32<T: AsRef<[u8]>>(hex: T) -> Result<u32, Error> {
|
||||
let hex = hex.as_ref();
|
||||
if hex.len() != 8 {
|
||||
bail!("Error while converting hex string to u32: unexpected string length");
|
||||
}
|
||||
|
||||
let mut bytes: [u8; 4] = unsafe { std::mem::uninitialized() };
|
||||
for i in 0..4 {
|
||||
bytes[i] = (hex_nibble(hex[i * 2])? << 4) + hex_nibble(hex[i * 2 + 1])?;
|
||||
}
|
||||
|
||||
Ok(u32::from_be_bytes(bytes))
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ProcFsNetIPv6Route {
|
||||
pub dest: Ipv6Addr,
|
||||
pub prefix: u8,
|
||||
pub gateway: Ipv6Addr,
|
||||
pub metric: u32,
|
||||
pub iface: String,
|
||||
}
|
||||
|
||||
pub fn read_proc_net_ipv6_route() -> Result<Vec<ProcFsNetIPv6Route>, Error> {
|
||||
let path = "/proc/net/ipv6_route";
|
||||
let file = OpenOptions::new().read(true).open(&path)?;
|
||||
let err = "Error while parsing '/proc/net/ipv6_route";
|
||||
|
||||
let mut result = Vec::new();
|
||||
for line in BufReader::new(&file).lines() {
|
||||
let content = line?;
|
||||
if content.is_empty() { continue; }
|
||||
let mut iter = content.split_whitespace();
|
||||
|
||||
let dest = iter.next().ok_or(format_err!("{}", err))?;
|
||||
let dest_prefix_len = iter.next().ok_or(format_err!("{}", err))?;
|
||||
for _ in 0..2 { iter.next(); }
|
||||
let nexthop = iter.next().ok_or(format_err!("{}", err))?;
|
||||
let metric = iter.next().ok_or(format_err!("{}", err))?;
|
||||
for _ in 0..3 { iter.next(); }
|
||||
let iface = iter.next().ok_or(format_err!("{}", err))?;
|
||||
|
||||
result.push(ProcFsNetIPv6Route {
|
||||
dest: hexstr_to_ipv6addr(dest)?,
|
||||
prefix: hexstr_to_u8(dest_prefix_len)?,
|
||||
gateway: hexstr_to_ipv6addr(nexthop)?,
|
||||
metric: hexstr_to_u32(metric)?,
|
||||
iface: iface.to_string(),
|
||||
});
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue