zond_engine/system/interface/
ext.rs1use pnet::datalink::NetworkInterface;
8use pnet::ipnetwork::{IpNetwork, Ipv4Network, Ipv6Network};
9
10pub trait NetworkInterfaceExtension {
12 fn get_ipv4_nets(&self) -> Vec<Ipv4Network>;
14 fn get_ipv6_nets(&self) -> Vec<Ipv6Network>;
16 fn get_ipv4_range(&self) -> Option<Ipv4Network>;
18}
19
20impl NetworkInterfaceExtension for NetworkInterface {
21 fn get_ipv4_nets(&self) -> Vec<Ipv4Network> {
22 self.ips
23 .iter()
24 .filter_map(|ip| {
25 if let IpNetwork::V4(ipv4) = ip {
26 Some(*ipv4)
27 } else {
28 None
29 }
30 })
31 .collect()
32 }
33
34 fn get_ipv6_nets(&self) -> Vec<Ipv6Network> {
35 self.ips
36 .iter()
37 .filter_map(|ip| {
38 if let IpNetwork::V6(ipv6) = ip {
39 Some(*ipv6)
40 } else {
41 None
42 }
43 })
44 .collect()
45 }
46
47 fn get_ipv4_range(&self) -> Option<Ipv4Network> {
48 self.get_ipv4_nets()
50 .into_iter()
51 .find(|net| !net.ip().is_loopback())
52 }
53}
54
55#[cfg(test)]
65mod tests {
66 use super::*;
67 use std::net::{Ipv4Addr, Ipv6Addr};
68
69 fn mock_interface() -> NetworkInterface {
70 NetworkInterface {
71 name: "test0".to_string(),
72 description: "".to_string(),
73 index: 0,
74 mac: None,
75 ips: vec![
76 IpNetwork::V4(Ipv4Network::new(Ipv4Addr::new(127, 0, 0, 1), 8).unwrap()),
77 IpNetwork::V4(Ipv4Network::new(Ipv4Addr::new(192, 168, 1, 100), 24).unwrap()),
78 IpNetwork::V6(
79 Ipv6Network::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 128).unwrap(),
80 ),
81 ],
82 flags: 0,
83 }
84 }
85
86 #[test]
87 fn get_ipv4_nets() {
88 let intf = mock_interface();
89 let v4s = intf.get_ipv4_nets();
90 assert_eq!(v4s.len(), 2);
91 assert_eq!(v4s[0].ip(), Ipv4Addr::new(127, 0, 0, 1));
92 assert_eq!(v4s[1].ip(), Ipv4Addr::new(192, 168, 1, 100));
93 }
94
95 #[test]
96 fn get_ipv6_nets() {
97 let intf = mock_interface();
98 let v6s = intf.get_ipv6_nets();
99 assert_eq!(v6s.len(), 1);
100 assert_eq!(v6s[0].ip(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
101 }
102
103 #[test]
104 fn get_ipv4_range_ignores_loopback() {
105 let intf = mock_interface();
106 let best_range = intf.get_ipv4_range();
107 assert!(best_range.is_some());
108 assert_eq!(best_range.unwrap().ip(), Ipv4Addr::new(192, 168, 1, 100));
109 }
110}