diff --git a/archer_router_wifi_fix_20260923-050642.sh b/archer_router_wifi_fix_20260923-050642.sh new file mode 100755 index 0000000..efc4cd4 --- /dev/null +++ b/archer_router_wifi_fix_20260923-050642.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +#=============================================================================== +# archer_router_wifi_fix.sh — diagnose a "stuck" home router +# +# SUMMARY (context from the TP-Link/Archer troubleshooting session): +# Symptom: Wi-Fi associates with full signal, DHCP lease obtained, but the +# router's own IPv4 (ping, admin page, DNS, IPv4 internet) is unreachable over +# WLAN. IPv6, DHCP and client-to-client bridging may still work — this is the +# classic "half-wedged" router: the management plane is hung, so a web/browser +# "Reboot" button often never executes. +# Fix: HARD power-cycle (unplug 30–60 s, replug, wait ~2 min). Verify Wi-Fi +# in isolation (bind each test to an interface) so an ethernet cable / second +# NIC can't mask the result. If it still hangs with stock firmware, replace +# the unit. +# +# USE: bash archer_router_wifi_fix.sh # full diagnostic +# bash archer_router_wifi_fix.sh wifi # verify Wi-Fi path only (post-reboot) +# exit codes: 0 = all healthy, 1 = at least one check failed +#=============================================================================== +set -u +FAIL=0 +MODE="${1:-all}" # all | wifi + +log() { printf '\033[1;34m[%s]\033[0m %s\n' "$(date +%H:%M:%S)" "$*"; } +ok() { printf ' \033[1;32mPASS\033[0m %s\n' "$*"; } +bad() { printf ' \033[1;31mFAIL\033[0m %s\n' "$*"; FAIL=1; } + +#--- targets --------------------------------------------------------------- +GW=$(ip -4 route show default | awk '/^default/{print $3; exit}') +IFACES=$(ip -4 -o addr show scope global | awk '{print $2}' | sort -u) + +# if only wifi, filter to wireless NICs +if [ "$MODE" = "wifi" ]; then + IFACES=$(iw dev 2>/dev/null | awk '/Interface/{print $2}') +fi + +log "Gateway (IPv4): ${GW:-NONE (no default route)}" +log "Interfaces to test: $IFACES" + +#--- per-interface checks -------------------------------------------------- +for I in $IFACES; do + [ -n "$I" ] || continue + IP=$(ip -4 -o addr show dev "$I" scope global | awk '{print $4}') + log "== $I ($IP) ==" + + [ -n "$IP" ] && ok "has IPv4 $IP" || { bad "no IPv4 on $I"; continue; } + + if [ -n "$GW" ]; then + if ping -I "$I" -c 3 -W 2 "$GW" >/dev/null 2>&1; then + ok "ping $GW on $I" + else + bad "ping $GW on $I" + if [ "$MODE" != "wifi" ]; then + printf ' > router not answering IPv4 on %s — try HARD power-cycle\n' "$I" + fi + fi + fi + + if curl -sI -m 6 --interface "$I" "http://$GW" -o /dev/null >/dev/null 2>&1; then + ok "admin page http://$GW reachable" + else + bad "admin page http://$GW not reachable" + fi + + if curl -sI -m 8 --interface "$I" https://example.com -o /dev/null >/dev/null 2>&1; then + ok "IPv4 internet via $I (example.com)" + else + bad "IPv4 internet via $I" + fi + + # IPv6 path (optional signal) + if ping -6 -c 2 -W 2 "fe80::1%$I" >/dev/null 2>&1; then + ok "IPv6 link-local reachable (router alive on v6)" + else + log "IPv6 check skipped/absent on $I" + fi +done + +#--- DNS ------------------------------------------------------------------ +log "DNS" +if getent hosts example.com >/dev/null 2>&1; then + ok "system DNS resolves" +else + bad "system DNS does not resolve" +fi + +printf '\n' +if [ "$FAIL" -eq 0 ]; then + log "RESULT: all checks OK" +else + log "RESULT: failures found -> if the 'ping ' failed above, do a" + log " HARD power-cycle of the router (unplug 30–60s), wait 2 min," + log " then re-run: bash archer_router_wifi_fix.sh wifi" +fi +exit $FAIL \ No newline at end of file