use std::net::IpAddr; use futures::stream::TryStreamExt; use netlink_packet_route::{ neighbour::{NeighbourAddress, NeighbourAttribute, NeighbourMessage}, route::RouteType, }; use rtnetlink::{new_connection, IpVersion}; use tokio::sync::mpsc::Sender; use crate::{Error, Result}; pub struct Netlink; pub async fn neighbours(tx: Sender) -> Result<()> { let (connection, handle, _) = new_connection().unwrap(); tokio::spawn(connection); handle .neighbours() .get() .set_family(IpVersion::V4) .execute() .or_else(|res| async { Err(Error::from(res)) }) .try_filter_map(|msg| async { Ok(filter(msg)) }) .try_for_each(|host| { let tx = tx.clone(); async move { tx.send(host).await.map_err(Error::from) } }) .await } pub fn filter(msg: NeighbourMessage) -> Option { if msg.header.kind != RouteType::Unicast { return None; } msg.attributes.into_iter().find_map(|attr| match attr { NeighbourAttribute::Destination(NeighbourAddress::Inet(ip)) => Some(ip.into()), NeighbourAttribute::Destination(NeighbourAddress::Inet6(ip)) => Some(ip.into()), _ => None, }) }