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
41 changes: 31 additions & 10 deletions bin/omarchy-network-status
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,31 @@ case "${1:-}" in
;;
esac

# Prefer an active physical NetworkManager device (Wi-Fi or Ethernet). A
# full-tunnel VPN or Tailscale exit node can own the default route, but the
# panel should still describe the LAN connection the user actually joined.
# If NetworkManager reports no active physical device, fall back to the main
# routing table's lowest-metric default route.
physical_device() {
local dev

dev=$(nmcli -t -f DEVICE,TYPE,STATE dev status 2>/dev/null | awk -F: '
$2 == "wifi" && $3 ~ /^connected/ { print $1; exit }
$2 == "ethernet" && $3 ~ /^connected/ { print $1; exit }
')

if [[ -n $dev ]]; then
echo "$dev"
return
fi

ip -j route show table main default 2>/dev/null | jq -r 'sort_by(.metric // 0) | .[0].dev // ""'
}

print_status() {
local device nm state ssid signal freq

device=$(ip route get "$internet_probe" 2>/dev/null | awk '{ for (i = 1; i <= NF; i++) if ($i == "dev") { print $(i + 1); exit } }')
device=$(physical_device)

if [[ -z $device ]]; then
printf 'disconnected\t\t\t\n'
Expand Down Expand Up @@ -83,18 +104,18 @@ print_ping_samples() {
}

print_verbose() {
local route_json iface gw src prefix link

route_json=$(ip -j route get "$internet_probe" 2>/dev/null)
[[ -z $route_json ]] && return

iface=$(jq -r '.[0].dev // ""' <<<"$route_json" 2>/dev/null)
gw=$(jq -r '.[0].gateway // ""' <<<"$route_json" 2>/dev/null)
src=$(jq -r '.[0].prefsrc // ""' <<<"$route_json" 2>/dev/null)
local iface gw src prefix link

iface=$(physical_device)
[[ -z $iface ]] && return

prefix=$(ip -j addr show "$iface" 2>/dev/null | jq -r '.[0].addr_info[]? | select(.family == "inet") | .prefixlen // ""' 2>/dev/null | head -n 1)
src=$(ip -j -4 addr show "$iface" 2>/dev/null | jq -r '.[0].addr_info[]? | select(.family == "inet" and .scope == "global") | .local // ""' 2>/dev/null | head -n 1)
prefix=$(ip -j -4 addr show "$iface" 2>/dev/null | jq -r '.[0].addr_info[]? | select(.family == "inet" and .scope == "global") | .prefixlen // ""' 2>/dev/null | head -n 1)

gw=$(ip -j route show dev "$iface" default 2>/dev/null | jq -r 'sort_by(.metric // 0) | .[0].gateway // ""' 2>/dev/null)
if [[ -z $gw ]]; then
gw=$(ip -j route show table main default 2>/dev/null | jq -r 'sort_by(.metric // 0) | .[0].gateway // ""' 2>/dev/null)
fi

printf 'iface\t%s\n' "$iface"
printf 'ip\t%s\n' "$src"
Expand Down
65 changes: 65 additions & 0 deletions test/shell.d/network-status-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/bin/bash

set -euo pipefail

source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"

test_tmp=$(mktemp -d)
stub_bin="$test_tmp/bin"
trap 'rm -rf "$test_tmp"' EXIT
mkdir -p "$stub_bin"

cat >"$stub_bin/nmcli" <<'SH'
#!/bin/bash

printf '%s\n' "$*" >>"$NMCLI_CALLS"

case "$*" in
"-t -f DEVICE,TYPE,STATE dev status")
printf '%s\n' 'wlp4s0:wifi:connected'
printf '%s\n' 'tailscale0:tun:connected (externally)'
;;
*)
exit 1
;;
esac
SH

cat >"$stub_bin/ip" <<'SH'
#!/bin/bash

printf '%s\n' "$*" >>"$IP_CALLS"

case "$*" in
"-j route show table main default")
printf '%s\n' '[{"dst":"default","gateway":"192.0.2.1","dev":"wlp4s0","prefsrc":"192.0.2.15","metric":600}]'
;;
"-j route show dev wlp4s0 default")
printf '%s\n' '[{"dst":"default","gateway":"192.0.2.1","dev":"wlp4s0","prefsrc":"192.0.2.15","metric":600}]'
;;
"-j -4 addr show wlp4s0")
printf '%s\n' '[{"addr_info":[{"family":"inet","local":"192.0.2.15","prefixlen":24,"scope":"global"}]}]'
;;
*)
exit 1
;;
esac
SH

cat >"$stub_bin/ping" <<'SH'
#!/bin/bash
printf '%s\n' '64 bytes from target: icmp_seq=1 ttl=64 time=1.0 ms'
SH

chmod +x "$stub_bin/nmcli" "$stub_bin/ip" "$stub_bin/ping"

IP_CALLS="$test_tmp/ip-calls" NMCLI_CALLS="$test_tmp/nmcli-calls" PATH="$stub_bin:$ROOT/bin:$PATH" \
"$ROOT/bin/omarchy-network-status" --verbose >"$test_tmp/status"

grep -qx $'iface\twlp4s0' "$test_tmp/status" || fail "network status selects the physical NetworkManager device"
grep -qx $'ip\t192.0.2.15' "$test_tmp/status" || fail "network status reports the physical interface address"
grep -qx $'gateway\t192.0.2.1' "$test_tmp/status" || fail "network status reports the physical gateway"
grep -q 'route get' "$test_tmp/ip-calls" && fail "network status bypasses policy routing installed by VPNs"
grep -q 'tailscale0' "$test_tmp/status" && fail "network status ignores Tailscale/TUN devices"

pass "network status ignores VPN and Tailscale devices"