1 use std::io; 2 use std::os::fd::AsFd; 3 use std::os::fd::AsRawFd; 4 use std::os::fd::FromRawFd; 5 use std::os::fd::OwnedFd; 6 7 use crate::Error; 8 use crate::Link; 9 use crate::Result; 10 11 /// Represents a bpf iterator for reading kernel data structures. This requires 12 /// Linux 5.8. 13 /// 14 /// This implements [`std::io::Read`] for reading bytes from the iterator. 15 /// Methods require working with raw bytes. You may find libraries such as 16 /// [`plain`](https://crates.io/crates/plain) helpful. 17 #[derive(Debug)] 18 pub struct Iter { 19 fd: OwnedFd, 20 } 21 22 impl Iter { 23 /// Create a new `Iter` wrapping the provided `Link`. new(link: &Link) -> Result<Self>24 pub fn new(link: &Link) -> Result<Self> { 25 let link_fd = link.as_fd().as_raw_fd(); 26 let fd = unsafe { libbpf_sys::bpf_iter_create(link_fd) }; 27 if fd < 0 { 28 return Err(Error::from(io::Error::last_os_error())); 29 } 30 Ok(Self { 31 fd: unsafe { OwnedFd::from_raw_fd(fd) }, 32 }) 33 } 34 } 35 36 impl io::Read for Iter { read(&mut self, buf: &mut [u8]) -> io::Result<usize>37 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { 38 let bytes_read = 39 unsafe { libc::read(self.fd.as_raw_fd(), buf.as_mut_ptr() as *mut _, buf.len()) }; 40 if bytes_read < 0 { 41 return Err(io::Error::last_os_error()); 42 } 43 Ok(bytes_read as usize) 44 } 45 } 46