From 945910d319f19bd99c74d121f48842225af0cadc Mon Sep 17 00:00:00 2001 From: Frostie314159 Date: Mon, 25 Mar 2024 00:45:13 +0100 Subject: [PATCH] Added if_indextoname function. (#2340) * Added if_indextoname function. * Added changelog. * Fixed pointer cast. * Applied suggestions. --- changelog/2340.added.md | 1 + src/net/if_.rs | 21 +++++++++++++++++---- test/test_net.rs | 11 +++++++++++ 3 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 changelog/2340.added.md diff --git a/changelog/2340.added.md b/changelog/2340.added.md new file mode 100644 index 0000000000..9d120d4879 --- /dev/null +++ b/changelog/2340.added.md @@ -0,0 +1 @@ +Add if_indextoname function. diff --git a/src/net/if_.rs b/src/net/if_.rs index c66b5dc0b3..5b6c2e77a5 100644 --- a/src/net/if_.rs +++ b/src/net/if_.rs @@ -3,9 +3,9 @@ //! Uses Linux and/or POSIX functions to resolve interface names like "eth0" //! or "socan1" into device numbers. -use std::fmt; -use crate::{Error, NixPath, Result}; -use libc::c_uint; +use std::{ffi::{CStr, CString}, fmt}; +use crate::{errno::Errno, Error, NixPath, Result}; +use libc::{c_uint, IF_NAMESIZE}; #[cfg(not(solarish))] /// type alias for InterfaceFlags @@ -14,7 +14,7 @@ pub type IflagsType = libc::c_int; /// type alias for InterfaceFlags pub type IflagsType = libc::c_longlong; -/// Resolve an interface into a interface number. +/// Resolve an interface into an interface number. pub fn if_nametoindex(name: &P) -> Result { let if_index = name .with_nix_path(|name| unsafe { libc::if_nametoindex(name.as_ptr()) })?; @@ -26,6 +26,19 @@ pub fn if_nametoindex(name: &P) -> Result { } } +/// Resolve an interface number into an interface. +pub fn if_indextoname(index: c_uint) -> Result { + // We need to allocate this anyway, so doing it directly is faster. + let mut buf = vec![0u8; IF_NAMESIZE]; + + let return_buf = unsafe { + libc::if_indextoname(index, buf.as_mut_ptr().cast()) + }; + + Errno::result(return_buf.cast())?; + Ok(CStr::from_bytes_until_nul(buf.as_slice()).unwrap().to_owned()) +} + libc_bitflags!( /// Standard interface flags, used by `getifaddrs` pub struct InterfaceFlags: IflagsType { diff --git a/test/test_net.rs b/test/test_net.rs index faba8503fe..46a3efd501 100644 --- a/test/test_net.rs +++ b/test/test_net.rs @@ -13,3 +13,14 @@ const LOOPBACK: &[u8] = b"loop"; fn test_if_nametoindex() { if_nametoindex(LOOPBACK).expect("assertion failed"); } + +#[test] +fn test_if_indextoname() { + let loopback_index = if_nametoindex(LOOPBACK).expect("assertion failed"); + assert_eq!( + if_indextoname(loopback_index) + .expect("assertion failed") + .as_bytes(), + LOOPBACK + ); +}