1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
use std::fs::File;
use std::io::{Error, ErrorKind, Read};
use NetworkExt;
#[derive(Debug)]
pub struct NetworkData {
old_in: u64,
old_out: u64,
current_in: u64,
current_out: u64,
}
impl NetworkExt for NetworkData {
fn get_income(&self) -> u64 {
self.current_in - self.old_in
}
fn get_outcome(&self) -> u64 {
self.current_out - self.old_out
}
}
pub fn new() -> NetworkData {
NetworkData {
old_in: 0,
old_out: 0,
current_in: 0,
current_out: 0,
}
}
fn read_things() -> Result<(u64, u64), Error> {
fn read_interface_stat(iface: &str, typ: &str) -> Result<u64, Error> {
let mut file = File::open(format!("/sys/class/net/{}/statistics/{}_bytes", iface, typ))?;
let mut content = String::new();
file.read_to_string(&mut content)?;
content.trim()
.parse()
.map_err(|_| Error::new(ErrorKind::Other, "Failed to parse network stat"))
}
let default_interface = {
let mut file = File::open("/proc/net/route")?;
let mut content = String::new();
file.read_to_string(&mut content)?;
content.lines()
.filter(|l| l.split_whitespace().nth(2).map(|l| l != "00000000").unwrap_or(false))
.last()
.and_then(|l| l.split_whitespace().nth(0))
.ok_or_else(|| Error::new(ErrorKind::Other, "Default device not found"))?
.to_owned()
};
Ok((read_interface_stat(&default_interface, "rx")?,
read_interface_stat(&default_interface, "tx")?))
}
pub fn update_network(n: &mut NetworkData) {
if let Ok((new_in, new_out)) = read_things() {
n.old_in = n.current_in;
n.old_out = n.current_out;
n.current_in = new_in;
n.current_out = new_out;
}
}