Skip to main content

etherip_xdp/
interface.rs

1use std::fmt::Debug;
2
3#[allow(dead_code)]
4pub fn index_to_name(index: InterfaceId) -> Result<String, std::io::Error> {
5    let index = if let Some(index) = index.inner() {
6        index
7    } else {
8        return Err(std::io::Error::new(
9            std::io::ErrorKind::InvalidInput,
10            "interface index is unspecified",
11        ));
12    };
13    let ifname_buf = [0u8; libc::IFNAMSIZ];
14    let ret = unsafe { libc::if_indextoname(index, ifname_buf.as_ptr() as *mut libc::c_char) };
15    if ret.is_null() {
16        return Err(std::io::Error::last_os_error());
17    }
18
19    let name = unsafe { std::ffi::CStr::from_ptr(ret) }
20        .to_str()
21        .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?
22        .to_owned();
23    Ok(name)
24}
25
26pub fn name_to_index(name: &str) -> Result<InterfaceId, std::io::Error> {
27    let name = std::ffi::CString::new(name)
28        .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e))?;
29    let index = unsafe { libc::if_nametoindex(name.as_ptr() as *const libc::c_char) };
30    if index == 0 {
31        return Err(std::io::Error::last_os_error());
32    }
33    Ok(InterfaceId::new(index))
34}
35
36#[derive(Debug, Clone, Copy, PartialEq, Hash, Eq)]
37pub struct InterfaceId {
38    if_index: libc::c_uint,
39}
40
41#[allow(dead_code)]
42impl InterfaceId {
43    pub const UNSPECIFIED: Self = Self { if_index: 0 };
44
45    pub(crate) fn new(if_index: libc::c_uint) -> Self {
46        Self { if_index }
47    }
48
49    pub(crate) fn inner_unchecked(&self) -> libc::c_uint {
50        self.if_index
51    }
52
53    pub(crate) fn inner(&self) -> Option<libc::c_uint> {
54        if self.if_index == 0 {
55            None
56        } else {
57            Some(self.if_index)
58        }
59    }
60
61    pub fn is_unspecified(&self) -> bool {
62        self.if_index == 0
63    }
64}
65
66#[derive(Debug, Clone, PartialEq)]
67pub struct Interface {
68    pub if_id: InterfaceId,
69    pub if_name: String,
70}