mprober_lib/network/
mod.rs1mod network_stat;
2
3use std::{
4 collections::HashSet,
5 hash::{Hash, Hasher},
6 io::ErrorKind,
7 thread::sleep,
8 time::Duration,
9};
10
11pub use network_stat::*;
12
13use crate::scanner_rust::{generic_array::typenum::U1024, ScannerAscii, ScannerError};
14
15#[derive(Default, Debug, Clone, Eq)]
16pub struct Network {
17 pub interface: String,
18 pub stat: NetworkStat,
19}
20
21impl Hash for Network {
22 #[inline]
23 fn hash<H: Hasher>(&self, state: &mut H) {
24 self.interface.hash(state)
25 }
26}
27
28impl PartialEq for Network {
29 #[inline]
30 fn eq(&self, other: &Network) -> bool {
31 self.interface.eq(&other.interface)
32 }
33}
34
35pub fn get_networks() -> Result<Vec<Network>, ScannerError> {
45 let mut sc: ScannerAscii<_, U1024> = ScannerAscii::scan_path2("/proc/net/dev")?;
46
47 for _ in 0..2 {
48 sc.drop_next_line()?.ok_or(ErrorKind::UnexpectedEof)?;
49 }
50
51 let mut networks = Vec::with_capacity(1);
52
53 while let Some(interface) = sc.next_until_raw(":")? {
54 let interface = unsafe { String::from_utf8_unchecked(interface) };
55
56 let receive_bytes = sc.next_u64()?.ok_or(ErrorKind::UnexpectedEof)?;
57
58 for _ in 0..7 {
59 sc.drop_next()?.ok_or(ErrorKind::UnexpectedEof)?;
60 }
61
62 let transmit_bytes = sc.next_u64()?.ok_or(ErrorKind::UnexpectedEof)?;
63
64 let stat = NetworkStat {
65 receive_bytes,
66 transmit_bytes,
67 };
68
69 let network = Network {
70 interface,
71 stat,
72 };
73
74 networks.push(network);
75
76 sc.drop_next_line()?.ok_or(ErrorKind::UnexpectedEof)?;
77 }
78
79 Ok(networks)
80}
81
82pub fn get_networks_with_speed(
99 interval: Duration,
100) -> Result<Vec<(Network, NetworkSpeed)>, ScannerError> {
101 let pre_networks = get_networks()?;
102
103 let pre_networks_length = pre_networks.len();
104
105 let mut pre_networks_hashset = HashSet::with_capacity(pre_networks_length);
106
107 for pre_network in pre_networks {
108 pre_networks_hashset.insert(pre_network);
109 }
110
111 sleep(interval);
112
113 let networks = get_networks()?;
114
115 let mut networks_with_speed = Vec::with_capacity(networks.len().min(pre_networks_length));
116
117 for network in networks {
118 if let Some(pre_network) = pre_networks_hashset.get(&network) {
119 let network_speed = pre_network.stat.compute_speed(&network.stat, interval);
120
121 networks_with_speed.push((network, network_speed));
122 }
123 }
124
125 Ok(networks_with_speed)
126}