initial commit (ugly but works): linkspeed <netdev name>

This commit is contained in:
ddidderr 2024-12-04 18:24:02 +01:00
commit 83357007b0
Signed by: ddidderr
GPG Key ID: 3841F1C27E6F0E14
5 changed files with 102 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

7
Cargo.lock generated Normal file
View File

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "linkspeed"
version = "0.1.0"

7
Cargo.toml Normal file
View File

@ -0,0 +1,7 @@
[package]
name = "linkspeed"
version = "0.1.0"
edition = "2024"
rust-version = "1.85"
[dependencies]

2
rust-toolchain.toml Normal file
View File

@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"

85
src/main.rs Normal file
View File

@ -0,0 +1,85 @@
use std::{
env,
fs::File,
io::{self, Read, Seek, SeekFrom},
thread::sleep,
time::{Duration, Instant},
};
struct LinkSpeed {
rx: File,
tx: File,
rx_bytes: u64,
tx_bytes: u64,
time: Instant,
}
impl LinkSpeed {
pub fn new(dev: String) -> io::Result<Self> {
let rx_bytes_file = File::open(format!("/sys/class/net/{dev}/statistics/rx_bytes"))?;
let tx_bytes_file = File::open(format!("/sys/class/net/{dev}/statistics/tx_bytes"))?;
Ok(Self {
rx: rx_bytes_file,
tx: tx_bytes_file,
rx_bytes: 0,
tx_bytes: 0,
time: Instant::now(),
})
}
fn read_bytes(file: &mut File) -> io::Result<u64> {
file.seek(SeekFrom::Start(0))?;
let mut buf = String::new();
file.read_to_string(&mut buf)?;
Ok(buf.trim().parse().unwrap_or(0))
}
fn update(&mut self) -> io::Result<(u64, u64)> {
let rx_bytes = Self::read_bytes(&mut self.rx)?;
let tx_bytes = Self::read_bytes(&mut self.tx)?;
let mut rx_diff = rx_bytes - self.rx_bytes;
let mut tx_diff = tx_bytes - self.tx_bytes;
if self.rx_bytes == 0 {
self.rx_bytes = rx_bytes;
rx_diff = 0;
}
if self.tx_bytes == 0 {
self.tx_bytes = tx_bytes;
tx_diff = 0;
}
self.rx_bytes = rx_bytes;
self.tx_bytes = tx_bytes;
Ok((rx_diff, tx_diff))
}
pub fn get_measurement(&mut self) -> (f64, f64) {
let elapsed = self.time.elapsed().as_secs_f64();
let (rx, tx) = self.update().unwrap();
let rx_speed = rx as f64 / elapsed;
let tx_speed = tx as f64 / elapsed;
self.time = Instant::now();
(rx_speed, tx_speed)
}
}
fn main() {
let netdev_name = env::args().nth(1).expect("No network device provided");
let mut link_speed = LinkSpeed::new(netdev_name).expect("Failed to create LinkSpeed object");
loop {
let (rx_speed, tx_speed) = link_speed.get_measurement();
println!(
"RX: {:.0} MBit/s, TX: {:.0} MBit/s",
rx_speed / 1024.0 / 1024.0 * 8.0,
tx_speed / 1024.0 / 1024.0 * 8.0
);
sleep(Duration::from_millis(1000));
}
}