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