summaryrefslogtreecommitdiffstats
path: root/vendor/sysinfo/src/freebsd/network.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/sysinfo/src/freebsd/network.rs')
-rw-r--r--vendor/sysinfo/src/freebsd/network.rs199
1 files changed, 199 insertions, 0 deletions
diff --git a/vendor/sysinfo/src/freebsd/network.rs b/vendor/sysinfo/src/freebsd/network.rs
new file mode 100644
index 000000000..e58ad823a
--- /dev/null
+++ b/vendor/sysinfo/src/freebsd/network.rs
@@ -0,0 +1,199 @@
+// Take a look at the license at the top of the repository in the LICENSE file.
+
+use std::collections::{hash_map, HashMap};
+use std::mem::MaybeUninit;
+
+use super::utils;
+use crate::{NetworkExt, NetworksExt, NetworksIter};
+
+macro_rules! old_and_new {
+ ($ty_:expr, $name:ident, $old:ident, $data:expr) => {{
+ $ty_.$old = $ty_.$name;
+ $ty_.$name = $data.$name;
+ }};
+}
+
+#[doc = include_str!("../../md_doc/networks.md")]
+pub struct Networks {
+ interfaces: HashMap<String, NetworkData>,
+}
+
+impl Networks {
+ pub(crate) fn new() -> Networks {
+ Networks {
+ interfaces: HashMap::new(),
+ }
+ }
+}
+
+impl NetworksExt for Networks {
+ fn iter(&self) -> NetworksIter {
+ NetworksIter::new(self.interfaces.iter())
+ }
+
+ fn refresh_networks_list(&mut self) {
+ unsafe {
+ self.refresh_interfaces(true);
+ }
+ // Remove interfaces which are gone.
+ self.interfaces.retain(|_, n| n.updated);
+ }
+
+ fn refresh(&mut self) {
+ unsafe {
+ self.refresh_interfaces(false);
+ }
+ }
+}
+
+impl Networks {
+ unsafe fn refresh_interfaces(&mut self, refresh_all: bool) {
+ let mut nb_interfaces: libc::c_int = 0;
+ if !utils::get_sys_value(
+ &[
+ libc::CTL_NET,
+ libc::PF_LINK,
+ libc::NETLINK_GENERIC,
+ libc::IFMIB_SYSTEM,
+ libc::IFMIB_IFCOUNT,
+ ],
+ &mut nb_interfaces,
+ ) {
+ return;
+ }
+ if refresh_all {
+ // We don't need to update this value if we're not updating all interfaces.
+ for interface in self.interfaces.values_mut() {
+ interface.updated = false;
+ }
+ }
+ let mut data: libc::ifmibdata = MaybeUninit::zeroed().assume_init();
+ for row in 1..nb_interfaces {
+ let mib = [
+ libc::CTL_NET,
+ libc::PF_LINK,
+ libc::NETLINK_GENERIC,
+ libc::IFMIB_IFDATA,
+ row,
+ libc::IFDATA_GENERAL,
+ ];
+
+ if !utils::get_sys_value(&mib, &mut data) {
+ continue;
+ }
+ if let Some(name) = utils::c_buf_to_string(&data.ifmd_name) {
+ let data = &data.ifmd_data;
+ match self.interfaces.entry(name) {
+ hash_map::Entry::Occupied(mut e) => {
+ let mut interface = e.get_mut();
+
+ old_and_new!(interface, ifi_ibytes, old_ifi_ibytes, data);
+ old_and_new!(interface, ifi_obytes, old_ifi_obytes, data);
+ old_and_new!(interface, ifi_ipackets, old_ifi_ipackets, data);
+ old_and_new!(interface, ifi_opackets, old_ifi_opackets, data);
+ old_and_new!(interface, ifi_ierrors, old_ifi_ierrors, data);
+ old_and_new!(interface, ifi_oerrors, old_ifi_oerrors, data);
+ interface.updated = true;
+ }
+ hash_map::Entry::Vacant(e) => {
+ if !refresh_all {
+ // This is simply a refresh, we don't want to add new interfaces!
+ continue;
+ }
+ e.insert(NetworkData {
+ ifi_ibytes: data.ifi_ibytes,
+ old_ifi_ibytes: 0,
+ ifi_obytes: data.ifi_obytes,
+ old_ifi_obytes: 0,
+ ifi_ipackets: data.ifi_ipackets,
+ old_ifi_ipackets: 0,
+ ifi_opackets: data.ifi_opackets,
+ old_ifi_opackets: 0,
+ ifi_ierrors: data.ifi_ierrors,
+ old_ifi_ierrors: 0,
+ ifi_oerrors: data.ifi_oerrors,
+ old_ifi_oerrors: 0,
+ updated: true,
+ });
+ }
+ }
+ }
+ }
+ }
+}
+
+#[doc = include_str!("../../md_doc/network_data.md")]
+pub struct NetworkData {
+ /// Total number of bytes received over interface.
+ ifi_ibytes: u64,
+ old_ifi_ibytes: u64,
+ /// Total number of bytes transmitted over interface.
+ ifi_obytes: u64,
+ old_ifi_obytes: u64,
+ /// Total number of packets received.
+ ifi_ipackets: u64,
+ old_ifi_ipackets: u64,
+ /// Total number of packets transmitted.
+ ifi_opackets: u64,
+ old_ifi_opackets: u64,
+ /// Shows the total number of packets received with error. This includes
+ /// too-long-frames errors, ring-buffer overflow errors, CRC errors,
+ /// frame alignment errors, fifo overruns, and missed packets.
+ ifi_ierrors: u64,
+ old_ifi_ierrors: u64,
+ /// similar to `ifi_ierrors`
+ ifi_oerrors: u64,
+ old_ifi_oerrors: u64,
+ /// Whether or not the above data has been updated during refresh
+ updated: bool,
+}
+
+impl NetworkExt for NetworkData {
+ fn received(&self) -> u64 {
+ self.ifi_ibytes.saturating_sub(self.old_ifi_ibytes)
+ }
+
+ fn total_received(&self) -> u64 {
+ self.ifi_ibytes
+ }
+
+ fn transmitted(&self) -> u64 {
+ self.ifi_obytes.saturating_sub(self.old_ifi_obytes)
+ }
+
+ fn total_transmitted(&self) -> u64 {
+ self.ifi_obytes
+ }
+
+ fn packets_received(&self) -> u64 {
+ self.ifi_ipackets.saturating_sub(self.old_ifi_ipackets)
+ }
+
+ fn total_packets_received(&self) -> u64 {
+ self.ifi_ipackets
+ }
+
+ fn packets_transmitted(&self) -> u64 {
+ self.ifi_opackets.saturating_sub(self.old_ifi_opackets)
+ }
+
+ fn total_packets_transmitted(&self) -> u64 {
+ self.ifi_opackets
+ }
+
+ fn errors_on_received(&self) -> u64 {
+ self.ifi_ierrors.saturating_sub(self.old_ifi_ierrors)
+ }
+
+ fn total_errors_on_received(&self) -> u64 {
+ self.ifi_ierrors
+ }
+
+ fn errors_on_transmitted(&self) -> u64 {
+ self.ifi_oerrors.saturating_sub(self.old_ifi_oerrors)
+ }
+
+ fn total_errors_on_transmitted(&self) -> u64 {
+ self.ifi_oerrors
+ }
+}