diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib.rs | 3 | ||||
-rw-r--r-- | src/net/if_.rs | 48 | ||||
-rw-r--r-- | src/net/mod.rs | 1 |
3 files changed, 52 insertions, 0 deletions
@@ -34,6 +34,9 @@ pub mod mqueue; #[cfg(any(target_os = "linux", target_os = "macos"))] pub mod poll; +#[cfg(any(target_os = "linux"))] +pub mod net; + #[cfg(any(target_os = "linux", target_os = "android"))] pub mod sched; diff --git a/src/net/if_.rs b/src/net/if_.rs new file mode 100644 index 00000000..26028f93 --- /dev/null +++ b/src/net/if_.rs @@ -0,0 +1,48 @@ +//! Network interface name resolution. +//! +//! Uses Linux and/or POSIX functions to resolve interface names like "eth0" +//! or "socan1" into device numbers. + +use libc::{c_char, c_uint}; +use std::ffi::{CString, NulError}; +use std::io; + +/// Error that can occur during interface name resolution. +#[derive(Debug)] +pub enum NameToIndexError { + /// Failed to allocate a C-style string to for the syscall + NulError, + IOError(io::Error), +} + +impl From<NulError> for NameToIndexError { + fn from(_: NulError) -> NameToIndexError { + NameToIndexError::NulError + } +} + +impl From<io::Error> for NameToIndexError { + fn from(e: io::Error) -> NameToIndexError { + NameToIndexError::IOError(e) + } +} + +extern { + fn if_nametoindex(ifname: *const c_char) -> c_uint; +} + +/// Resolve an interface into a interface number. +pub fn name_to_index(name: &str) -> Result<c_uint, NameToIndexError> { + let name = try!(CString::new(name)); + + let if_index; + unsafe { + if_index = if_nametoindex(name.as_ptr()); + } + + if if_index == 0 { + return Err(NameToIndexError::from(io::Error::last_os_error())); + } + + Ok(if_index) +} diff --git a/src/net/mod.rs b/src/net/mod.rs new file mode 100644 index 00000000..e3e8ba2e --- /dev/null +++ b/src/net/mod.rs @@ -0,0 +1 @@ +pub mod if_; |