network_interface/target/
getifaddrs.rs

1use std::mem;
2use crate::{Error, Result};
3
4pub struct IfAddrIterator {
5    base: *mut libc::ifaddrs,
6    next: *mut libc::ifaddrs,
7}
8
9impl Iterator for IfAddrIterator {
10    type Item = libc::ifaddrs;
11
12    fn next(&mut self) -> Option<Self::Item> {
13        match unsafe { self.next.as_ref() } {
14            Some(ifaddrs) => {
15                self.next = ifaddrs.ifa_next;
16                Some(ifaddrs.to_owned())
17            }
18            None => None,
19        }
20    }
21}
22
23impl Drop for IfAddrIterator {
24    fn drop(&mut self) {
25        unsafe { libc::freeifaddrs(self.base) }
26    }
27}
28
29pub fn getifaddrs() -> Result<IfAddrIterator> {
30    let mut addr = mem::MaybeUninit::<*mut libc::ifaddrs>::uninit();
31    match unsafe { libc::getifaddrs(addr.as_mut_ptr()) } {
32        0 => Ok(IfAddrIterator {
33            base: unsafe { addr.assume_init() },
34            next: unsafe { addr.assume_init() },
35        }),
36        getifaddrs_result => Err(Error::GetIfAddrsError(
37            String::from("getifaddrs"),
38            getifaddrs_result,
39        )),
40    }
41}