fast_down/utils/
network.rs1use getifaddrs::{InterfaceFlags, getifaddrs};
2use std::net::IpAddr;
3
4pub fn get_available_local_ips() -> std::io::Result<Vec<InterfaceInfo>> {
5 const VIRTUAL_KEYWORDS: &[&str] = &[
6 "docker",
8 "veth",
9 "br-",
10 "utun",
12 "tun",
13 "tap",
14 "vboxnet",
16 "vmnet",
17 "lo",
19 "tailscale",
21 "zerotier",
22 "bridge",
23 "dummy",
25 "virtual",
26 "pseudo",
27 ];
28
29 let mut ips = Vec::new();
30 let interfaces = getifaddrs()?;
31 for interface in interfaces {
32 if interface.flags.contains(InterfaceFlags::UP)
33 && !interface.flags.contains(InterfaceFlags::LOOPBACK)
34 && let Some(ip_addr) = interface.address.ip_addr()
35 && !ip_addr.is_unspecified()
36 && !is_link_local(&ip_addr)
37 && {
38 let name = interface.name.to_lowercase();
39 !VIRTUAL_KEYWORDS.iter().any(|k| name.contains(k))
40 }
41 {
42 ips.push(InterfaceInfo {
43 name: interface.name,
44 ip: ip_addr,
45 });
46 }
47 }
48 Ok(ips)
49}
50
51fn is_link_local(ip: &IpAddr) -> bool {
52 match ip {
53 IpAddr::V4(v4) => v4.is_link_local(),
54 IpAddr::V6(v6) => (v6.segments()[0] & 0xffc0) == 0xfe80,
55 }
56}
57
58pub struct InterfaceInfo {
59 pub name: String,
60 pub ip: IpAddr,
61}