Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
nib: New module to add neighbor cache access
Browse files Browse the repository at this point in the history
chrysn committed Aug 29, 2024
1 parent 3d280a4 commit edb059c
Showing 3 changed files with 67 additions and 0 deletions.
1 change: 1 addition & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -74,6 +74,7 @@ fn main() {
"gcoap",
"gnrc",
"gnrc_icmpv6",
"gnrc_ipv6_nib",
"gnrc_pktbuf",
"gnrc_udp",
"ipv6",
2 changes: 2 additions & 0 deletions src/gnrc/mod.rs
Original file line number Diff line number Diff line change
@@ -5,6 +5,8 @@ pub mod ipv6;

pub mod netapi;
pub mod netreg;
#[cfg(riot_module_gnrc_ipv6_nib)]
pub mod nib;
#[deprecated(note = "Internally, use gnrc_pktbuf directly")]
pub(crate) use crate::gnrc_pktbuf as pktbuf;

64 changes: 64 additions & 0 deletions src/gnrc/nib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/// A single entry in the neighbor cache.
///
/// These can be obtained by iterating
pub struct NcEntry(riot_sys::gnrc_ipv6_nib_nc_t);

impl NcEntry {
pub fn l2addr(&self) -> &[u8] {
&self.0.l2addr[..self.0.l2addr_len as usize]
}

pub fn ipv6_addr(&self) -> &crate::gnrc::ipv6::Address {
// unsafe: It's repr(transparent) around it
unsafe { core::mem::transmute(&self.0.ipv6) }
}

#[doc(alias = "gnrc_ipv6_nib_nc_get_iface")]
pub fn iface(&self) -> Option<core::num::NonZero<usize>> {
let interface = unsafe { gnrc_ipv6_nib_nc_get_iface(&self.0) };
// Let's not get into size discussions
let interface = interface as usize;
interface.try_into()
}
}

/// Iterate over the Neighbor Cache.
#[doc(alias = "gnrc_ipv6_nib_nc_iter")]
pub fn all_nc_entries() -> impl Iterator<Item = NcEntry> {
// If we add anything like all_nc_entries_on_interface():
// // Interfaces are positive numbers; MAX is clearly out of range and allows us to have an easier
// // input type
// let interface = interface.map(|i| {
// riot_sys::libc::c_uint::try_from(usize::from(i)).unwrap_or(riot_sys::libc::c_uint::MAX)
// });

any_nc_query(0)
}

struct NcIterator {
interface: riot_sys::libc::c_uint,
state: *mut riot_sys::libc::c_void,
}

impl Iterator for NcIterator {
type Item = NcEntry;

fn next(&mut self) -> Option<Self::Item> {
let mut nc_entry = core::mem::MaybeUninit::<riot_sys::gnrc_ipv6_nib_nc_t>::uninit();
if unsafe {
riot_sys::gnrc_ipv6_nib_nc_iter(self.interface, &mut self.state, nc_entry.as_mut_ptr())
} {
let nc_entry = NcEntry(unsafe { nc_entry.assume_init() });
Some(nc_entry)
} else {
None
}
}
}

fn any_nc_query(interface: riot_sys::libc::c_uint) -> impl Iterator<Item = NcEntry> {
NcIterator {
interface,
state: core::ptr::null_mut(),
}
}

0 comments on commit edb059c

Please sign in to comment.