Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for /proc/net/route #162

Merged
merged 1 commit into from Nov 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
75 changes: 75 additions & 0 deletions src/net.rs
Expand Up @@ -628,6 +628,74 @@ pub fn dev_status() -> ProcResult<HashMap<String, DeviceStatus>> {
Ok(map)
}

/// An entry in the ipv4 route table
#[derive(Debug, Clone)]
pub struct RouteEntry {
/// Interface to which packets for this route will be sent
pub iface: String,
/// The destination network or destination host
pub destination: Ipv4Addr,
pub gateway: Ipv4Addr,
pub flags: u16,
/// Number of references to this route
pub refcnt: u16,
/// Count of lookups for the route
pub in_use: u16,
/// The 'distance' to the target (usually counted in hops)
pub metrics: u32,
pub mask: Ipv4Addr,
/// Default maximum transmission unit for TCP connections over this route
pub mtu: u32,
/// Default window size for TCP connections over this route
pub window: u32,
/// Initial RTT (Round Trip Time)
pub irtt: u32,
}

/// Reads the ipv4 route table
///
/// This data is from the `/proc/net/route` file
pub fn route() -> ProcResult<Vec<RouteEntry>> {
let file = FileWrapper::open("/proc/net/route")?;
let reader = BufReader::new(file);

let mut vec = Vec::new();

// First line is a header we need to skip
for line in reader.lines().skip(1) {
// Check if there might have been an IO error.
let line = line?;
let mut line = line.split_whitespace();
// network interface name, e.g. eth0
let iface = expect!(line.next());
let destination = from_str!(u32, expect!(line.next()), 16).to_ne_bytes().into();
let gateway = from_str!(u32, expect!(line.next()), 16).to_ne_bytes().into();
let flags = from_str!(u16, expect!(line.next()), 16);
let refcnt = from_str!(u16, expect!(line.next()), 10);
let in_use = from_str!(u16, expect!(line.next()), 10);
let metrics = from_str!(u32, expect!(line.next()), 10);
let mask = from_str!(u32, expect!(line.next()), 16).to_ne_bytes().into();
let mtu = from_str!(u32, expect!(line.next()), 10);
let window = from_str!(u32, expect!(line.next()), 10);
let irtt = from_str!(u32, expect!(line.next()), 10);
vec.push(RouteEntry {
iface: iface.to_string(),
destination,
gateway,
flags,
refcnt,
in_use,
metrics,
mask,
mtu,
window,
irtt,
});
}

Ok(vec)
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -721,4 +789,11 @@ mod tests {
println!("{:?}", entry);
}
}

#[test]
fn test_route() {
for entry in route().unwrap() {
println!("{:?}", entry);
}
}
}
4 changes: 3 additions & 1 deletion support.md
Expand Up @@ -100,12 +100,14 @@ This is an approximate list of all the files under the `/proc` mount, and an ind
* [ ] `/proc/mounts`
* [ ] `/proc/mtrr`
* [ ] `/proc/net`
* [ ] `/proc/net/arp`
* [x] `/proc/net/arp`
* [x] `/proc/net/dev`
* [ ] `/proc/net/dev_mcast`
* [ ] `/proc/net/igmp`
* [ ] `/proc/net/ipv6_route`
* [ ] `/proc/net/rarp`
* [ ] `/proc/net/raw`
* [x] `/proc/net/route`
* [ ] `/proc/net/snmp`
* [x] `/proc/net/tcp`
* [x] `/proc/net/udp`
Expand Down