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
75
use libc::{self, c_char, CTL_NET, NET_RT_IFLIST2, PF_ROUTE, RTM_IFINFO2};
use std::ptr::null_mut;
use sys::ffi;
use NetworkExt;
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,
}
}
pub fn update_network(n: &mut NetworkData) {
let mib = &mut [CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST2, 0];
let mut len = 0;
if unsafe { libc::sysctl(mib.as_mut_ptr(), 6, null_mut(), &mut len, null_mut(), 0) } < 0 {
return
}
let mut buf = Vec::with_capacity(len);
unsafe {
buf.set_len(len);
if libc::sysctl(mib.as_mut_ptr(), 6, buf.as_mut_ptr(), &mut len, null_mut(), 0) < 0 {
return
}
}
let buf = buf.as_ptr() as *const c_char;
let lim = unsafe { buf.offset(len as isize) };
let mut next = buf;
let mut totalibytes = 0u64;
let mut totalobytes = 0u64;
while next < lim {
unsafe {
let ifm = next as *const libc::if_msghdr;
next = next.offset((*ifm).ifm_msglen as isize);
if (*ifm).ifm_type == RTM_IFINFO2 as u8 {
let if2m: *const ffi::if_msghdr2 = ifm as *const ffi::if_msghdr2;
totalibytes += (*if2m).ifm_data.ifi_ibytes;
totalobytes += (*if2m).ifm_data.ifi_obytes;
}
}
}
n.old_in = n.current_in;
n.current_in = totalibytes;
n.old_out = n.current_out;
n.current_out = totalobytes;
}