feat(runtime): add op_network_interfaces (#12964)

Add an op to list the network interfaces on the system.

Prep work for #8137 and `os.networkInterfaces()` Node compat in std.

Refs denoland/deno_std#1436.
This commit is contained in:
Ben Noordhuis 2021-12-23 00:00:43 +01:00 committed by GitHub
parent 9391ba1098
commit 1678690c36
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 67 additions and 0 deletions

11
Cargo.lock generated
View file

@ -935,6 +935,7 @@ dependencies = [
"hyper",
"libc",
"log",
"netif",
"nix",
"notify",
"once_cell",
@ -2258,6 +2259,16 @@ dependencies = [
"thiserror",
]
[[package]]
name = "netif"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c9e642845c332c335e3125759b10145a972c1f413cb48cd6d7b96e81821f281"
dependencies = [
"libc",
"winapi 0.3.9",
]
[[package]]
name = "new_debug_unreachable"
version = "1.0.4"

View file

@ -70,6 +70,7 @@ http = "0.2.4"
hyper = { version = "0.14.12", features = ["server", "stream", "http1", "http2", "runtime"] }
libc = "0.2.106"
log = "0.4.14"
netif = "0.1.0"
notify = "=5.0.0-pre.12"
once_cell = "=1.9.0"
regex = "1.5.4"

View file

@ -25,6 +25,7 @@ pub fn init(maybe_exit_code: Option<Arc<AtomicI32>>) -> Extension {
("op_delete_env", op_sync(op_delete_env)),
("op_hostname", op_sync(op_hostname)),
("op_loadavg", op_sync(op_loadavg)),
("op_network_interfaces", op_sync(op_network_interfaces)),
("op_os_release", op_sync(op_os_release)),
("op_set_exit_code", op_sync(op_set_exit_code)),
("op_system_memory_info", op_sync(op_system_memory_info)),
@ -149,6 +150,60 @@ fn op_os_release(
Ok(release)
}
fn op_network_interfaces(
state: &mut OpState,
_: (),
_: (),
) -> Result<Vec<NetworkInterface>, AnyError> {
super::check_unstable(state, "Deno.networkInterfaces");
state.borrow_mut::<Permissions>().env.check_all()?;
Ok(netif::up()?.map(NetworkInterface::from).collect())
}
#[derive(serde::Serialize)]
struct NetworkInterface {
family: &'static str,
name: String,
address: String,
netmask: String,
scopeid: Option<u32>,
cidr: String,
mac: String,
}
impl From<netif::Interface> for NetworkInterface {
fn from(ifa: netif::Interface) -> Self {
let family = match ifa.address() {
std::net::IpAddr::V4(_) => "IPv4",
std::net::IpAddr::V6(_) => "IPv6",
};
let (address, range) = ifa.cidr();
let cidr = format!("{:?}/{}", address, range);
let name = ifa.name().to_owned();
let address = format!("{:?}", ifa.address());
let netmask = format!("{:?}", ifa.netmask());
let scopeid = ifa.scope_id();
let [b0, b1, b2, b3, b4, b5] = ifa.mac();
let mac = format!(
"{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
b0, b1, b2, b3, b4, b5
);
Self {
family,
name,
address,
netmask,
scopeid,
cidr,
mac,
}
}
}
// Copied from sys-info/lib.rs (then tweaked)
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]