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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
use std::net::SocketAddr; use macaddr::MacAddr; use nix::ifaddrs; use nix::net::if_::InterfaceFlags; use nix::sys::socket; use heim_common::prelude::*; use crate::Address; #[derive(Debug)] pub struct Nic(ifaddrs::InterfaceAddress); impl Nic { pub fn name(&self) -> &str { self.0.interface_name.as_str() } pub fn address(&self) -> Address { self.0 .address .as_ref() .expect("NIC stream should exclude entries without address") .into() } pub fn netmask(&self) -> Option<Address> { self.0.netmask.as_ref().map(Into::into) } pub fn broadcast(&self) -> Option<Address> { self.0.broadcast.as_ref().map(Into::into) } pub fn destination(&self) -> Option<Address> { self.0.destination.as_ref().map(Into::into) } pub fn is_up(&self) -> bool { self.0.flags.contains(InterfaceFlags::IFF_UP) } pub fn is_running(&self) -> bool { self.0.flags.contains(InterfaceFlags::IFF_RUNNING) } pub fn is_broadcast(&self) -> bool { self.0.flags.contains(InterfaceFlags::IFF_BROADCAST) } pub fn is_loopback(&self) -> bool { self.0.flags.contains(InterfaceFlags::IFF_LOOPBACK) } pub fn is_point_to_point(&self) -> bool { self.0.flags.contains(InterfaceFlags::IFF_POINTOPOINT) } pub fn is_multicast(&self) -> bool { self.0.flags.contains(InterfaceFlags::IFF_MULTICAST) } } pub async fn nic() -> Result<impl Stream<Item = Result<Nic>>> { let iter = ifaddrs::getifaddrs()?.filter_map(|addr| { if addr.address.is_some() { Some(Ok(Nic(addr))) } else { None } }); Ok(stream::iter(iter)) } impl From<&socket::SockAddr> for Address { fn from(s: &socket::SockAddr) -> Self { use nix::sys::socket::SockAddr::*; match *s { Inet(addr) => match addr.to_std() { SocketAddr::V4(addr) => Address::Inet(addr), SocketAddr::V6(addr) => Address::Inet6(addr), }, Link(addr) => Address::Link(MacAddr::from(addr.addr())), other => unimplemented!("Unknown sockaddr: {:?}", other), } } }