diff --git a/src/lib.rs b/src/lib.rs index 6b321ba2aa..942da345dd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,6 +31,9 @@ pub mod mount; #[cfg(any(target_os = "linux"))] pub mod mqueue; +#[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 0000000000..d62af4faa5 --- /dev/null +++ b/src/net/if_.rs @@ -0,0 +1,34 @@ +//! Network interface name resolution. +//! +//! Uses Linux and/or POSIX functions to resolve interface names like "eth0" +//! or "socan1" into device numbers. + +use libc; +use libc::c_uint; +use std::ffi::{CString, NulError}; +use ::{Result, Error}; + +/// Resolve an interface into a interface number. +pub fn if_nametoindex(name: &str) -> Result { + let name = match CString::new(name) { + Err(e) => match e { NulError(..) => { + // A NulError indicates that a '\0' was found inside the string, + // making it impossible to create valid C-String. To avoid having + // to create a new error type for this rather rare case, + // nix::Error's invalid_argument() constructor is used. + // + // We match the NulError individually here to ensure to avoid + // accidentally returning invalid_argument() for errors other than + // NulError (which currently don't exist). + return Err(Error::invalid_argument()); + }}, + Ok(s) => s + }; + + let if_index; + unsafe { + if_index = libc::if_nametoindex(name.as_ptr()); + } + + if if_index == 0 { Err(Error::last()) } else { Ok(if_index) } +} diff --git a/src/net/mod.rs b/src/net/mod.rs new file mode 100644 index 0000000000..eca5cfbb7a --- /dev/null +++ b/src/net/mod.rs @@ -0,0 +1,3 @@ +// To avoid clashing with the keyword "if", we use "if_" as the module name. +// The original header is called "net/if.h". +pub mod if_;