summaryrefslogtreecommitdiffhomepage
path: root/test/test-runner
diff options
context:
space:
mode:
authorJoakim Hulthe <joakim@hulthe.net>2024-07-05 16:25:32 +0200
committerJoakim Hulthe <joakim@hulthe.net>2024-07-16 15:46:33 +0200
commit71ef4709732d9b0ba052d957a6483c743d5746aa (patch)
tree14dc9da32f3e8ae0249a4b4109eb086b939b7a4e /test/test-runner
parent28a3776b3a7a35c4e1f964e9dcb9c4698afd7a68 (diff)
downloadmullvadvpn-71ef4709732d9b0ba052d957a6483c743d5746aa.tar.xz
mullvadvpn-71ef4709732d9b0ba052d957a6483c743d5746aa.zip
Add E2E test of CVE-2019-14899 mitigation
Diffstat (limited to 'test/test-runner')
-rw-r--r--test/test-runner/Cargo.toml2
-rw-r--r--test/test-runner/src/main.rs8
-rw-r--r--test/test-runner/src/net.rs40
3 files changed, 46 insertions, 4 deletions
diff --git a/test/test-runner/Cargo.toml b/test/test-runner/Cargo.toml
index 50f3ddda6a..31c817fb87 100644
--- a/test/test-runner/Cargo.toml
+++ b/test/test-runner/Cargo.toml
@@ -58,7 +58,7 @@ features = ["codec"]
default-features = false
[target.'cfg(unix)'.dependencies]
-nix = { version = "0.25", features = ["socket", "net"] }
+nix = { workspace = true }
[target.'cfg(target_os = "linux")'.dependencies]
rs-release = "0.1.7"
diff --git a/test/test-runner/src/main.rs b/test/test-runner/src/main.rs
index 79e11e0506..3fe91fb723 100644
--- a/test/test-runner/src/main.rs
+++ b/test/test-runner/src/main.rs
@@ -233,6 +233,14 @@ impl Service for TestServer {
net::get_interface_mtu(&interface)
}
+ async fn get_interface_mac(
+ self,
+ _: context::Context,
+ interface: String,
+ ) -> Result<Option<[u8; 6]>, test_rpc::Error> {
+ net::get_interface_mac(&interface)
+ }
+
async fn get_default_interface(self, _: context::Context) -> Result<String, test_rpc::Error> {
Ok(net::get_default_interface().to_owned())
}
diff --git a/test/test-runner/src/net.rs b/test/test-runner/src/net.rs
index 22de4da9c9..a12fa2776c 100644
--- a/test/test-runner/src/net.rs
+++ b/test/test-runner/src/net.rs
@@ -173,7 +173,6 @@ pub async fn send_ping(
#[cfg(unix)]
pub fn get_interface_ip(interface: &str) -> Result<IpAddr, test_rpc::Error> {
// TODO: IPv6
- use std::net::Ipv4Addr;
let addrs = nix::ifaddrs::getifaddrs().map_err(|error| {
log::error!("Failed to obtain interfaces: {}", error);
@@ -183,13 +182,13 @@ pub fn get_interface_ip(interface: &str) -> Result<IpAddr, test_rpc::Error> {
if addr.interface_name == interface {
if let Some(address) = addr.address {
if let Some(sockaddr) = address.as_sockaddr_in() {
- return Ok(IpAddr::V4(Ipv4Addr::from(sockaddr.ip())));
+ return Ok(IpAddr::V4(sockaddr.ip()));
}
}
}
}
- log::error!("Could not find tunnel interface");
+ log::error!("Could not find interface {interface:?}");
Err(test_rpc::Error::InterfaceNotFound)
}
@@ -215,6 +214,41 @@ fn get_interface_ip_for_family(
})
}
+#[cfg(target_os = "linux")]
+pub fn get_interface_mac(interface: &str) -> Result<Option<[u8; 6]>, test_rpc::Error> {
+ let addrs = nix::ifaddrs::getifaddrs().map_err(|error| {
+ log::error!("Failed to obtain interfaces: {}", error);
+ test_rpc::Error::Syscall
+ })?;
+
+ let mut interface_exists = false;
+
+ let mac_addr = addrs
+ .filter(|addr| addr.interface_name == interface)
+ .find_map(|addr| {
+ // sadly, the only way of distinguishing between "iface doesn't exist" and
+ // "iface has no mac addr" is to check if the interface appears anywhere in the list.
+ interface_exists = true;
+
+ let addr = addr.address?;
+ let link_addr = addr.as_link_addr()?;
+ let mac_addr = link_addr.addr()?;
+ Some(mac_addr)
+ });
+
+ if interface_exists {
+ Ok(mac_addr)
+ } else {
+ log::error!("Could not find interface {interface:?}");
+ Err(test_rpc::Error::InterfaceNotFound)
+ }
+}
+
+#[cfg(not(target_os = "linux"))]
+pub fn get_interface_mac(_interface: &str) -> Result<Option<[u8; 6]>, test_rpc::Error> {
+ unimplemented!("get_interface_mac")
+}
+
#[cfg(target_os = "windows")]
pub fn get_default_interface() -> &'static str {
use once_cell::sync::OnceCell;