Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name = "interfaces"
description = "A Rust library for interacting with network interfaces"
version = "0.0.8"
edition = "2021"
authors = ["Naoya Hatta <[email protected]>", "Arvid E Picciani <[email protected]>", "Andrew Dunham <[email protected]>"]
homepage = "https://github.com/andrew-d/interfaces-rs"
repository = "https://github.com/andrew-d/interfaces-rs"
Expand All @@ -12,10 +13,9 @@ build = "build.rs"
bitflags = "1.3.2"
lazy_static = "1.4.0"
libc = "0.2.103"
nix = "0.23.0"
nix = { version = "0.24.1", default-features = false, features = ["net"] }

[build-dependencies]
cc = "1"
handlebars = "0.29"
serde = "1.0"
serde_derive = "1.0"
cc = "1"
handlebars = "4"
serde = { version = "1.0", features = ["derive"] }
36 changes: 16 additions & 20 deletions build.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
extern crate cc;
extern crate handlebars as hbs;
#[macro_use]
extern crate serde_derive;

use std::convert::From;
use std::fs::File;
use std::io::{self, Read};
Expand All @@ -11,6 +6,9 @@ use std::process::exit;

use std::env;

use handlebars as hbs;
use serde::{Deserialize, Serialize};

fn main() {
let in_path = Path::new("src").join("constants.c.in");
let out_path = PathBuf::from(env::var_os("OUT_DIR").unwrap()).join("constants.c");
Expand Down Expand Up @@ -44,17 +42,15 @@ fn main() {

fn template_file(in_path: &PathBuf, out_path: &PathBuf) -> Result<(), Error> {
// Open and read the file.
let mut f = File::open(in_path)?;
let mut in_file = File::open(in_path)?;
let mut s = String::new();
f.read_to_string(&mut s)?;

let mut handlebars = hbs::Handlebars::new();
handlebars.register_template_string("template", s)?;
in_file.read_to_string(&mut s)?;

let mut f = File::create(out_path)?;
let handlebars = hbs::Handlebars::new();
let mut out_file = File::create(out_path)?;

let data = make_data();
handlebars.renderw("template", &data, &mut f)?;
handlebars.render_template_to_write(&s, &data, &mut out_file)?;

Ok(())
}
Expand All @@ -80,11 +76,11 @@ fn make_data() -> Context {
let anames: &[&str] = &["sizeof(struct ifreq)"];

let names = names
.into_iter()
.iter()
.map(|x| String::from(*x))
.collect::<Vec<String>>();
let anames = anames
.into_iter()
.iter()
.map(|x| String::from(*x))
.collect::<Vec<String>>();

Expand All @@ -102,25 +98,25 @@ struct Context {

#[derive(Debug)]
enum Error {
IoError(io::Error),
TemplateError(hbs::TemplateError),
RenderError(hbs::RenderError),
Io(io::Error),
Template(hbs::TemplateError),
Render(hbs::RenderError),
}

impl From<io::Error> for Error {
fn from(e: io::Error) -> Error {
Error::IoError(e)
Error::Io(e)
}
}

impl From<hbs::TemplateError> for Error {
fn from(e: hbs::TemplateError) -> Error {
Error::TemplateError(e)
Error::Template(e)
}
}

impl From<hbs::RenderError> for Error {
fn from(e: hbs::RenderError) -> Error {
Error::RenderError(e)
Error::Render(e)
}
}
22 changes: 7 additions & 15 deletions examples/ifconfig-simple.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
extern crate interfaces;

use std::iter;
use std::net;

use interfaces::{
Expand All @@ -9,7 +6,7 @@ use interfaces::{
};

// Flag mappings that ifconfig uses, in order.
const NAME_MAPPINGS: &'static [(flags::InterfaceFlags, &'static str)] = &[
const NAME_MAPPINGS: &[(flags::InterfaceFlags, &str)] = &[
(InterfaceFlags::IFF_UP, "UP"),
(InterfaceFlags::IFF_LOOPBACK, "LOOPBACK"),
(InterfaceFlags::IFF_BROADCAST, "BROADCAST"),
Expand All @@ -25,13 +22,10 @@ fn main() {

// Find the maximum alignment for our interface names.
let max_align = ifs.iter().map(|i| i.name.len() + 2).max().unwrap();

let full_align = iter::repeat(' ').take(max_align).collect::<String>();
let full_align = " ".repeat(max_align);

for i in ifs.iter() {
let name_align = iter::repeat(' ')
.take(max_align - i.name.len() - 2)
.collect::<String>();
let name_align = " ".repeat(max_align - i.name.len() - 2);

// Build the first line by printing the interface flags.
let first_line = {
Expand All @@ -55,10 +49,8 @@ fn main() {

if i.flags.contains(InterfaceFlags::IFF_LOOPBACK) {
println!("{}loop (Local Loopback)", full_align);
} else {
if let Ok(addr) = i.hardware_addr() {
println!("{}ether {}", full_align, addr);
}
} else if let Ok(addr) = i.hardware_addr() {
println!("{}ether {}", full_align, addr);
}

for addr in i.addresses.iter() {
Expand All @@ -80,7 +72,7 @@ fn main() {

fn format_addr(addr: &net::SocketAddr) -> String {
match addr {
&net::SocketAddr::V4(ref a) => format!("{}", a.ip()),
&net::SocketAddr::V6(ref a) => format!("{}", a.ip()),
net::SocketAddr::V4(a) => format!("{}", a.ip()),
net::SocketAddr::V6(a) => format!("{}", a.ip()),
}
}
2 changes: 0 additions & 2 deletions examples/ifupdown.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
extern crate interfaces;

use std::env;
use std::process::exit;

Expand Down
4 changes: 4 additions & 0 deletions src/constants.c.in
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,18 @@ constant_t* rust_get_constants() {
static constant_t constants[] = {
// Testable constants
{{~ #each test_constants as |c|}}

#ifdef {{c}}
{ "{{c}}", {{c}} },
#endif

{{~ /each}}

// "Always" constants
{{~ #each always_constants as |c|}}

{ "{{c}}", {{c}} },

{{/each}}

// End of list sentinel
Expand Down
9 changes: 5 additions & 4 deletions src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use std::mem;
use std::os::raw::c_char;
use std::ptr;

use lazy_static::lazy_static;

#[cfg(any(
target_os = "fuchsia",
target_os = "haiku",
Expand Down Expand Up @@ -74,7 +76,7 @@ lazy_static! {
}

// Convert from the C-provided type into a hashmap.
let ret = cvals
cvals
.into_iter()
.map(|v| {
// HashMap has a from_iter method that accepts (key, value) tuples.
Expand All @@ -83,14 +85,13 @@ lazy_static! {
v.value as ConstantType
)
})
.collect::<HashMap<_, _>>();
ret
.collect::<HashMap<_, _>>()
};
}

pub fn get_constant<S: AsRef<str>>(name: S) -> Option<ConstantType> {
// Since `u64` is `Copy`, we can dereference the constant directly
CONSTANTS.get(name.as_ref()).map(|v| *v)
CONSTANTS.get(name.as_ref()).copied()
}

#[cfg(test)]
Expand Down
4 changes: 1 addition & 3 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ use std::convert::From;
use std::error::Error;
use std::fmt;

use nix;

/// InterfacesError is the error type that is returned by all functions in this crate. See the
/// documentation on the individual variants for more information.
#[derive(Debug)]
Expand All @@ -21,7 +19,7 @@ impl InterfacesError {
/// Create a new instance of `InterfacesError` with the error set to the current value of the
/// libc `errno` variable.
pub fn last_os_error() -> InterfacesError {
return InterfacesError::Errno(nix::errno::Errno::last());
InterfacesError::Errno(nix::errno::Errno::last())
}
}

Expand Down
60 changes: 39 additions & 21 deletions src/ffi.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
#![allow(dead_code)]
#![allow(dead_code, non_camel_case_types)]

use std::mem;
use std::net;
use std::ptr;

use libc::{self, c_void, c_char, c_int, c_uint, c_ushort};
use libc::{self, c_char, c_int, c_uint, c_ushort, c_void};
use nix::sys::socket;

pub const IFNAMSIZ: usize = 16;
Expand Down Expand Up @@ -60,8 +59,9 @@ fn make_int16(hi: u8, lo: u8) -> u16 {
(lo as u16) | ((hi as u16) << 8)
}

#[allow(clippy::identity_op)]
pub fn convert_sockaddr(sa: *mut socket::sockaddr) -> Option<net::SocketAddr> {
if sa == ptr::null_mut() {
if sa.is_null() {
return None;
}

Expand All @@ -70,33 +70,51 @@ pub fn convert_sockaddr(sa: *mut socket::sockaddr) -> Option<net::SocketAddr> {
let sa: *const socket::sockaddr_in = unsafe { mem::transmute(sa) };
let sa = &unsafe { *sa };
let (addr, port) = (sa.sin_addr.s_addr, sa.sin_port);
(net::IpAddr::V4(net::Ipv4Addr::new(((addr & 0x000000FF) >> 0) as u8,
((addr & 0x0000FF00) >> 8) as u8,
((addr & 0x00FF0000) >> 16) as u8,
((addr & 0xFF000000) >> 24) as u8)),
port, 0, 0)
(
net::IpAddr::V4(net::Ipv4Addr::new(
((addr & 0x000000FF) >> 0) as u8,
((addr & 0x0000FF00) >> 8) as u8,
((addr & 0x00FF0000) >> 16) as u8,
((addr & 0xFF000000) >> 24) as u8,
)),
port,
0,
0,
)
}
libc::AF_INET6 => {
let sa: *const socket::sockaddr_in6 = unsafe { mem::transmute(sa) };
let sa = &unsafe { *sa };
let (addr, port, flowinfo, scope_id) = (sa.sin6_addr.s6_addr, sa.sin6_port, sa.sin6_flowinfo, sa.sin6_scope_id);
(net::IpAddr::V6(net::Ipv6Addr::new(make_int16(addr[0], addr[1]),
make_int16(addr[2], addr[3]),
make_int16(addr[4], addr[5]),
make_int16(addr[6], addr[7]),
make_int16(addr[8], addr[9]),
make_int16(addr[10], addr[11]),
make_int16(addr[12], addr[13]),
make_int16(addr[14], addr[15]),
)),
port, flowinfo, scope_id)
let (addr, port, flowinfo, scope_id) = (
sa.sin6_addr.s6_addr,
sa.sin6_port,
sa.sin6_flowinfo,
sa.sin6_scope_id,
);
(
net::IpAddr::V6(net::Ipv6Addr::new(
make_int16(addr[0], addr[1]),
make_int16(addr[2], addr[3]),
make_int16(addr[4], addr[5]),
make_int16(addr[6], addr[7]),
make_int16(addr[8], addr[9]),
make_int16(addr[10], addr[11]),
make_int16(addr[12], addr[13]),
make_int16(addr[14], addr[15]),
)),
port,
flowinfo,
scope_id,
)
}
_ => return None,
};

let sa = match addr {
net::IpAddr::V4(addr) => net::SocketAddr::V4(net::SocketAddrV4::new(addr, port)),
net::IpAddr::V6(addr) => net::SocketAddr::V6(net::SocketAddrV6::new(addr, port, flowinfo, scope_id)),
net::IpAddr::V6(addr) => {
net::SocketAddr::V6(net::SocketAddrV6::new(addr, port, flowinfo, scope_id))
}
};
Some(sa)
}
Expand Down
2 changes: 2 additions & 0 deletions src/flags.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use bitflags::bitflags;

bitflags! {
/// Represents a set of flags that describe the state of an interface. This corresponds to the
/// flags that are returned from the `SIOCGIFFLAGS` syscall
Expand Down
Loading