summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs3
-rw-r--r--src/net/if_.rs48
-rw-r--r--src/net/mod.rs1
3 files changed, 52 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 512b5403..65db8bfe 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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_;