From be15035ad473517f1bad5caabef69ffccaeb46ef Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Fri, 30 Jan 2026 14:39:05 +0100 Subject: [PATCH] Use /proc/net/route instead of ip route command Fix #811, allegedly /proc/net/route is almost always available, and no additional dependency is needed at all. --- daemon/src/stats.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/daemon/src/stats.rs b/daemon/src/stats.rs index fd63a02..be390a0 100644 --- a/daemon/src/stats.rs +++ b/daemon/src/stats.rs @@ -181,11 +181,8 @@ pub struct RouteStatus { } pub async fn get_route_status() -> Json { - let mut cmd = Command::new("busybox"); - cmd.args(["ip", "route"]); - - let has_default_route = match get_cmd_output(cmd).await { - Ok(output) => output.lines().any(|line| line.starts_with("default ")), + let has_default_route = match check_default_route().await { + Ok(result) => result, Err(err) => { log::warn!("Failed to check default route: {err}"); // More likely than not, this is a portability issue. The logic hasn't been fully @@ -196,3 +193,14 @@ pub async fn get_route_status() -> Json { Json(RouteStatus { has_default_route }) } + +// Checks for an IPv4 default route by reading /proc/net/route +// instead of shelling out to `ip route`, which may not be available on all devices. +async fn check_default_route() -> std::io::Result { + let contents = tokio::fs::read_to_string("/proc/net/route").await?; + Ok(contents.lines().skip(1).any(|line| { + line.split_whitespace() + .nth(1) + .is_some_and(|dest| dest == "00000000") + })) +}