etherip-xdp 0.2.0

EtherIP implementation using XDP for Linux, in Rust.
Documentation
use futures::TryStreamExt;

use crate::interface::InterfaceId;

#[allow(dead_code)]
pub struct NeighborManager {
    handle: rtnetlink::NeighbourHandle,
}

impl NeighborManager {
    pub(crate) fn new(handle: &super::RtnetlinkConnection) -> Self {
        Self {
            handle: handle.handle.neighbours(),
        }
    }

    pub async fn neigh_get(
        &self,
        if_id: InterfaceId,
        addr: std::net::IpAddr,
    ) -> Result<Option<Vec<u8>>, std::io::Error> {
        let mut neigh_msg = netlink_packet_route::neighbour::NeighbourMessage::default();
        neigh_msg.header.family = match addr {
            std::net::IpAddr::V4(_) => netlink_packet_route::AddressFamily::Inet,
            std::net::IpAddr::V6(_) => netlink_packet_route::AddressFamily::Inet6,
        };
        neigh_msg.attributes.push(
            netlink_packet_route::neighbour::NeighbourAttribute::Destination(match addr {
                std::net::IpAddr::V4(v4) => {
                    netlink_packet_route::neighbour::NeighbourAddress::Inet(v4)
                }
                std::net::IpAddr::V6(v6) => {
                    netlink_packet_route::neighbour::NeighbourAddress::Inet6(v6)
                }
            }),
        );
        neigh_msg.header.ifindex = if_id.inner_unchecked();
        let mut req = self.handle.get();
        *(req.message_mut()) = neigh_msg;
        let response = req.execute();
        futures::pin_mut!(response);
        while let Some(response) = response
            .try_next()
            .await
            .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?
        {
            for neigh in response.attributes.iter() {
                if let netlink_packet_route::neighbour::NeighbourAttribute::LinkLocalAddress(addr) =
                    neigh
                {
                    if addr == &[0, 0, 0, 0, 0, 0] {
                        continue;
                    }
                    return Ok(Some(addr.clone()));
                }
            }
        }
        Ok(None)
    }
}