inherface 0.3.1

Retrieve a system's Network Interfaces on Linux
Documentation
use crate::{Error, Result};
use std::mem;

pub struct IfAddrIterator {
    base: *mut libc::ifaddrs,
    next: *mut libc::ifaddrs,
}

impl Iterator for IfAddrIterator {
    type Item = libc::ifaddrs;

    fn next(&mut self) -> Option<Self::Item> {
        match unsafe { self.next.as_ref() } {
            Some(ifaddrs) => {
                self.next = ifaddrs.ifa_next;
                Some(ifaddrs.to_owned())
            }
            // when pointer is null (usually after end of linked list)
            None => None,
        }
    }
}

impl Drop for IfAddrIterator {
    fn drop(&mut self) {
        unsafe { libc::freeifaddrs(self.base) }
    }
}

/// Returns an Iterator over the linked list returned by `getifaddrs`
///
/// https://man7.org/linux/man-pages/man3/getifaddrs.3.html
pub fn getifaddrs() -> Result<IfAddrIterator> {
    let mut addr = mem::MaybeUninit::<*mut libc::ifaddrs>::uninit();
    match unsafe { libc::getifaddrs(addr.as_mut_ptr()) } {
        0 => Ok(IfAddrIterator {
            base: unsafe { addr.assume_init() },
            next: unsafe { addr.assume_init() },
        }),
        getifaddrs_result => Err(Error::GetIfAddrsError(
            String::from("getifaddrs"),
            getifaddrs_result,
        )),
    }
}