#!/bin/sh ############################################################################## # # # __ __.__ .__ # # / \ / \__|______ ____ | | ____ ______ ______ # # \ \/\/ / \_ __ \/ __ \| | _/ __ \ / ___// ___/ # # \ /| || | \/\ ___/| |_\ ___/ \___ \ \___ \ # # \__/\ / |__||__| \___ >____/\___ >____ >____ > # # \/ \/ \/ \/ \/ # # __________ __ # # \______ \ ____ ______ ____________/ |_ # # | _// __ \\____ \ / _ \_ __ \ __\ # # | | \ ___/| |_> > <_> ) | \/| | # # |____|_ /\___ > __/ \____/|__| |__| # # \/ \/|__| # # # # # # # # Author: JB_1366 # ############################################################################## # shellcheck shell=sh disable=SC2086,SC2155,SC3043 # ############################################################################## SCRIPT_VERSION="1.3.8" INSTALL_DIR="/jffs/addons/wireless_report" REPORT_SCRIPT="$INSTALL_DIR/wirelessreport.sh" CONF_FILE="$INSTALL_DIR/webui.conf" [ -f "$CONF_FILE" ] && . "$CONF_FILE" USB_PATH=$(ls -d /tmp/mnt/*/wirelessreport 2>/dev/null | head -n 1) [ -z "$USB_PATH" ] && OLD=$(ls -d /tmp/mnt/*/gen_report 2>/dev/null | head -n 1) && [ -n "$OLD" ] && { USB_PATH="${OLD%/*}/wirelessreport"; mkdir -p "$USB_PATH"; mv "$OLD"/* "$USB_PATH/"; rm -rf "$OLD"; } [ -z "$USB_PATH" ] && USB_PATH=$(ls -d /tmp/mnt/*/ 2>/dev/null | grep -v "defaults" | head -n 1 | sed 's/\/$//')/wirelessreport [ -z "$USB_PATH" ] || [ "$USB_PATH" = "/wirelessreport" ] && USB_PATH="$INSTALL_DIR/data" mkdir -p "$USB_PATH" export PATH="/usr/sbin:/usr/bin:/sbin:/bin:/jffs/bin" KNOWN_DB="$USB_PATH/known_macs.db"; HISTORY_DB="$USB_PATH/rssi_history.db" OUT_FILE="/tmp/wireless.asp"; YAZ_CLIENTS="/jffs/addons/YazDHCP.d/DHCP_clients" SEEN_MACS="/tmp/seen_macs.txt"; ARP_CACHE="/tmp/arp_cache.tmp" YAZ_CACHE="/tmp/yaz_cache.tmp"; NEW_HISTORY="/tmp/rssi_new.db" Q_RELAY="/tmp/q_relay.tmp"; MAIN_ROWS="/tmp/main_rows.tmp" NODE_ROWS="/tmp/node_rows.tmp"; ALL_ROWS="/tmp/all_rows.tmp" CYAN='\033[0;36m'; GREEN='\033[0;32m'; RED='\033[0;31m'; NC='\033[0m' [ -f "/tmp/home/root/.ssh/id_dropbear" ] && SSH_KEY="/tmp/home/root/.ssh/id_dropbear" || SSH_KEY="/jffs/.ssh/id_dropbear" doScriptUpdateFromAMTM=true GITHUB="https://raw.githubusercontent.com/JB1366/Wireless_Report/main/wirelessreport.sh" REMOTE_VER=$(curl -s -m 2 "$GITHUB" | grep "SCRIPT_VERSION=" | head -n 1 | cut -d'"' -f2 | tr -cd '0-9.') [ -n "$REMOTE_VER" ] && [ "$REMOTE_VER" != "$SCRIPT_VERSION" ] && HOVER_TEXT="Current Script v$SCRIPT_VERSION
New Version v$REMOTE_VER available" || HOVER_TEXT="SCRIPT v$SCRIPT_VERSION" [ ${#HOVER_TEXT} -le 14 ] && V_WIDTH="100px" || V_WIDTH="190px" [ "$REPORT_UNIT" = "C" ] && D_FMT="+%-d-%b %-H:%M" || D_FMT="+%b-%-d %-H:%M" [ "$REPORT_UNIT" = "C" ] && T_FMT="+%-d-%b %-H:%M:%S" || T_FMT="+%b-%-d %-H:%M:%S" > $SEEN_MACS; > $MAIN_ROWS; > $NODE_ROWS; > $ALL_ROWS; > $NEW_HISTORY; > $Q_RELAY ########################## # Inject Menu Function # ########################## inject_menu() { source /usr/sbin/helper.sh SYSTEM_MENU="/www/require/modules/menuTree.js" TEMP_MENU="/tmp/menuTree.js" TAB_LABEL="Wireless Report" WEB_PAGE="$INSTALL_DIR/wireless.asp" RAM_PAGE="/tmp/wireless.asp" [ -f "$CONF_FILE" ] && sed -i '/^INSTALLED_PAGE=/d' "$CONF_FILE" nvram get rc_support | grep -q am_addons if [ $? != 0 ]; then logger -t "Wireless Report" "This firmware does not support addons!" exit 5 fi mkdir -p "$INSTALL_DIR" if [ ! -f "$RAM_PAGE" ]; then echo "Generating Report... Please refresh." > "$RAM_PAGE" fi if [ ! -f "$WEB_PAGE" ]; then echo "Initial Install: Creating placeholder." echo "Generating Report... Please refresh." > "$WEB_PAGE" fi [ -f "$CONF_FILE" ] && sed -i '/^INSTALLED_PAGE=/d' "$CONF_FILE" am_get_webui_page "$WEB_PAGE" if [ "$am_webui_page" = "none" ]; then logger -t "Wireless Report" "Unable to install Wireless Report" exit 5 fi cp "$WEB_PAGE" "/www/user/$am_webui_page" rm -f "$WEB_PAGE" [ -f "/tmp/menuTree.js" ] && sed -i '/Wireless Report/d' /tmp/menuTree.js 2>/dev/null if [ -f "$CONF_FILE" ]; then echo "INSTALLED_PAGE=$am_webui_page" >> "$CONF_FILE" else echo "INSTALLED_PAGE=$am_webui_page" > "$CONF_FILE" fi if [ ! -f "$TEMP_MENU" ]; then cp "$SYSTEM_MENU" /tmp/ mount -o bind "$TEMP_MENU" "$SYSTEM_MENU" fi sed -i "/index: \"menu_Wireless\"/,/{url: \"NULL\", tabName: \"__INHERIT__\"}/ {/{url: \"NULL\", tabName: \"__INHERIT__\"}/i \\ {url: \"$am_webui_page\", tabName: \"$TAB_LABEL\"}, }" "$TEMP_MENU" logger -t "Wireless Report" "Mounting Menu/Wireless TAB/Wireless Report as $am_webui_page" umount "$SYSTEM_MENU" && mount -o bind "$TEMP_MENU" "$SYSTEM_MENU" umount "/www/user/$am_webui_page" 2>/dev/null mount -o bind "$RAM_PAGE" "/www/user/$am_webui_page" service restart_httpd >/dev/null 2>&1 || killall -HUP httpd >/dev/null 2>&1 "$INSTALL_DIR/wirelessreport.sh" & } ############################## # Script Install Functions # ############################## ScriptUpdateFromAMTM() { if ! "$doScriptUpdateFromAMTM" then printf "Automatic script updates via AMTM are currently disabled.\n\n" return 1 fi if [ $# -gt 0 ] && [ "$1" = "check" ] then return 0 fi do_update echo -e "\n${GREEN}Wireless Report successfully updated${NC}" return "$?" } do_update(){ [ -z "$REMOTE_VER" ] && REMOTE_VER=$(curl -sfL --connect-timeout 3 "$GITHUB" | grep -m1 'SCRIPT_VERSION=' | cut -d'"' -f2) curl -sfL --connect-timeout 3 "$GITHUB" -o "$REPORT_SCRIPT" chmod +x "$REPORT_SCRIPT" 2>/dev/null echo -e "\n${GREEN}Downloading latest version (v$REMOTE_VER)${NC}" } check_version() { local if [ -f "$REPORT_SCRIPT" ]; then LOCAL_VER=$(grep "SCRIPT_VERSION=" "$REPORT_SCRIPT" | head -n 1 | cut -d'"' -f2 2>/dev/null) else LOCAL_VER="NOT INSTALLED" fi REMOTE_DATA=$(curl -sfL --connect-timeout 2 "$GITHUB") if [ $? -ne 0 ] || [ -z "$REMOTE_DATA" ]; then REMOTE_VER="" else REMOTE_VER=$(echo "$REMOTE_DATA" | grep "SCRIPT_VERSION=" | head -n 1 | cut -d'"' -f2 2>/dev/null) fi echo -e "${CYAN}==================================================${NC}" echo -e "${CYAN} WIRELESS REPORT AIMESH ${NC}" echo -e "${CYAN}==================================================${NC}" if [ -z "$REMOTE_VER" ]; then echo -e " STATUS: ${RED}[Offline]${NC} Could not reach GitHub" elif [ "$LOCAL_VER" = "NOT INSTALLED" ]; then echo -e " STATUS: [Ready] Latest available is v$REMOTE_VER" elif [ "$LOCAL_VER" != "$REMOTE_VER" ]; then echo -e " STATUS: ${RED}[UPDATE AVAILABLE] v$REMOTE_VER${NC} (Current: v$LOCAL_VER)" else echo -e " STATUS: [Up to date] v$LOCAL_VER" fi echo -e "${CYAN}==================================================${NC}" } check_storage() { echo -e "${CYAN}[*] Checking for Storage...${NC}" if echo "$USB_PATH" | grep -q "/tmp/mnt/"; then echo -e "${GREEN}[+] USB Found: Using $USB_PATH for reports and history.${NC}" else echo -e "${YELLOW}[!] No USB detected: Using JFFS at $USB_PATH.${NC}" fi mkdir -p "$USB_PATH" 2>/dev/null } show_menu() { echo -e "" echo -e " (1) Install/Update Wireless Report" echo -e " (2) Uninstall Wireless Report" echo -e " (3) Temperature Unit: °F(def) or °C" echo -e " (4) Set Router/Node Nicknames" echo -e " (e) Exit" echo -e "" echo -e "${CYAN}==================================================${NC}" printf " Selection: " } check_ssh_environment() { mkdir -p "$INSTALL_DIR" 2>/dev/null [ ! -f "$CONF_FILE" ] && touch "$CONF_FILE" echo -e "${CYAN}[*] Verifying Passwordless SSH Environment...${NC}" if [ ! -f "$SSH_KEY" ]; then echo -e "${RED}[!] ERROR: SSH Key not found.${NC}" echo -e "${RED}[!] Please setup passwordless SSH Key(s) and try again.${NC}" return 1 fi SSH_PORT=$(nvram get sshd_port) [ -z "$SSH_PORT" ] && SSH_PORT=22 NODE_IPS=$(nvram get asus_device_list | sed 's/2$' | awk -F '>' '{print $2 "|" $3}' | sort -t . -k 4,4n) NODE_USER=$(nvram get http_username) if [ -z "$NODE_IPS" ]; then echo -e "${RED}[!] No AiMesh Nodes detected. This script requires a AiMesh environment.${NC}" echo -e "${RED}[!] Installation aborted.${NC}" return 1 fi any_success=0 VALID_NODES="" for line in $NODE_IPS; do ALIAS=$(echo "$line" | cut -d'|' -f1) IP=$(echo "$line" | cut -d'|' -f2) echo -ne "[*] Testing Passwordless SSH to $ALIAS ($IP) on port $SSH_PORT... " /usr/bin/ssh -p "$SSH_PORT" -i "$SSH_KEY" -o StrictHostKeyChecking=no -o ConnectTimeout=3 -o BatchMode=yes "${NODE_USER}@${IP}" "exit" >/dev/null 2>&1 if [ $? -eq 0 ]; then echo -e "${GREEN}AUTHENTICATED${NC}" any_success=1 VALID_NODES="$VALID_NODES $ALIAS|$IP" else echo -e "${RED}FAILED${NC}" fi done if [ "$any_success" -eq 0 ]; then echo -e "${RED}[!] Error: No nodes authenticated. Setup SSH Keys and try again.${NC}" return 1 fi sed -i '/SSH_NODES=/d' "$CONF_FILE" echo "SSH_NODES=\"$VALID_NODES\"" >> "$CONF_FILE" } do_install() { mkdir -p "$INSTALL_DIR" 2>/dev/null if [ -f "$REPORT_SCRIPT" ]; then LOCAL_VER=$(grep "SCRIPT_VERSION=" "$REPORT_SCRIPT" | head -n 1 | cut -d'"' -f2 2>/dev/null) REMOTE_DATA=$(curl -s --connect-timeout 2 "$GITHUB") REMOTE_VER=$(echo "$REMOTE_DATA" | grep "SCRIPT_VERSION=" | head -n 1 | cut -d'"' -f2 2>/dev/null) if [ "$LOCAL_VER" = "$REMOTE_VER" ] && [ -n "$REMOTE_VER" ]; then echo -e "\n${GREEN}[i] You are already on the latest version (v$LOCAL_VER).${NC}" printf " Do you want to reinstall/overwrite anyway? (y/n): " read -r confirm_reinstall if [ "$confirm_reinstall" != "y" ] && [ "$confirm_reinstall" != "Y" ]; then return fi fi if do_update; then service restart_httpd >/dev/null 2>&1 pause return 0 fi fi if [ "$(nvram get jffs2_scripts)" != "1" ]; then echo -e "${RED}[!] ERROR: JFFS custom scripts not enabled.${NC}" return 1 fi check_storage if [ -n "$USB_PATH" ]; then touch "$USB_PATH/rssi_history.db" touch "$USB_PATH/known_macs.db" fi check_ssh_environment || return 1 echo -e "${CYAN}[*] Processing Wireless Report Files...${NC}" [ ! -f "$CONF_FILE" ] && touch "$CONF_FILE" if ! grep -q "REPORT_UNIT=" "$CONF_FILE" 2>/dev/null; then echo "REPORT_UNIT=F" >> "$CONF_FILE" fi [ -f "/tmp/menuTree.js" ] && sed -i '/Wireless Report/d' /tmp/menuTree.js 2>/dev/null if [ -f "$CONF_FILE" ]; then OLD_PAGE=$(grep "INSTALLED_PAGE=" "$CONF_FILE" | cut -d'=' -f2) if [ -n "$OLD_PAGE" ]; then umount -l "/www/user/$OLD_PAGE" 2>/dev/null rm -f "/www/user/$OLD_PAGE" fi fi curl -s --connect-timeout 5 "$GITHUB" -o "$REPORT_SCRIPT" chmod +x "$REPORT_SCRIPT" 2>/dev/null if [ -f "$REPORT_SCRIPT" ]; then inject_menu [ ! -f "/jffs/scripts/services-start" ] && echo "#!/bin/sh" > /jffs/scripts/services-start sed -i "\|$REPORT_SCRIPT|d" /jffs/scripts/services-start echo "sh $REPORT_SCRIPT inject # Inject Wireless Report" >> /jffs/scripts/services-start chmod +x /jffs/scripts/services-start [ ! -f "/jffs/scripts/service-event" ] && echo "#!/bin/sh" > /jffs/scripts/service-event sed -i "/wireless_report/d" /jffs/scripts/service-event echo 'if [ "$1" = "restart" ] && [ "$2" = "wireless_report" ]; then sh '$REPORT_SCRIPT'; fi # Wireless Report' >> /jffs/scripts/service-event chmod +x /jffs/scripts/service-event service restart_httpd >/dev/null 2>&1 || killall -HUP httpd >/dev/null 2>&1 sh "$REPORT_SCRIPT" >/dev/null 2>&1 & echo -e "\n${GREEN}SUCCESS: Installation complete!${NC}" echo -e "${CYAN}[i] Use Option 4 if you wish to set custom nicknames.${NC}" else echo -e "${RED}[!] ERROR: Download failed.${NC}" fi pause } do_uninstall() { if [ ! -d "$INSTALL_DIR" ]; then echo -e "\n${RED}[!] Wireless Report is not installed.${NC}" pause return fi echo -e "\n${RED}[!] WARNING: Removing Wireless Report...${NC}" printf " Are you sure? (y/n): " read confirm if [ "$confirm" = "y" ] || [ "$confirm" = "Y" ]; then [ -f "$CONF_FILE" ] && . "$CONF_FILE" if mount | grep -q "menuTree.js"; then echo -e "${CYAN}[*] Detaching menu for cleaning...${NC}" umount -l /www/require/modules/menuTree.js >/dev/null 2>&1 sed -i '/tabName:[[:space:]]*"Wireless Report"/d' /tmp/menuTree.js if grep -q "tabName" /tmp/menuTree.js; then mount --bind /tmp/menuTree.js /www/require/modules/menuTree.js else echo -e "${CYAN}[*] Restoring menu to factory default.${NC}" fi fi if [ -n "$INSTALLED_PAGE" ]; then logger -t "Wireless Report" "Unmounting Menu/Wireless TAB/Wireless Report" umount -l "/www/user/$INSTALLED_PAGE" >/dev/null 2>&1 rm -f "/www/user/$INSTALLED_PAGE" >/dev/null 2>&1 fi sed -i "\|$REPORT_SCRIPT|d" /jffs/scripts/services-start sed -i "/wireless_report/d" /jffs/scripts/service-event service restart_httpd >/dev/null 2>&1 || killall -HUP httpd >/dev/null 2>&1 rm -rf "$INSTALL_DIR" 2>/dev/null rm -f /tmp/wireless.asp 2>/dev/null rm -rf "$USB_PATH" 2>/dev/null echo -e "${GREEN}[+] Uninstalled. Wireless Report tab is gone.${NC}" fi pause } pause() { printf "\nPress [Enter] to return..."; read discard; } set_temp_unit() { clear echo -e "${CYAN}==================================================${NC}" echo -e " TEMPERATURE UNIT SETTINGS " echo -e "${CYAN}==================================================${NC}" [ -f "$CONF_FILE" ] && . "$CONF_FILE" CURRENT_UNIT=${REPORT_UNIT:-F} echo -e " Current Setting: ${GREEN}$CURRENT_UNIT${NC}" echo -e "" echo -e " (1) Fahrenheit (°F) - Default" echo -e " (2) Celsius (°C)" echo -e " (r) Return to main menu" echo -e "" printf " Selection: " read t_choice case "$t_choice" in 1) NEW_UNIT="F" ;; 2) NEW_UNIT="C" ;; r|R) return ;; *) echo -e "${RED}Invalid selection.${NC}"; sleep 1; set_temp_unit; return ;; esac if [ ! -f "$CONF_FILE" ]; then echo "REPORT_UNIT=$NEW_UNIT" > "$CONF_FILE" else sed -i '/REPORT_UNIT=/d' "$CONF_FILE" echo "REPORT_UNIT=$NEW_UNIT" >> "$CONF_FILE" fi echo -e "${GREEN}[+] Temperature unit set to $NEW_UNIT${NC}" [ -f "$REPORT_SCRIPT" ] && sh "$REPORT_SCRIPT" >/dev/null 2>&1 & pause } set_nicknames() { clear RAW_NODES=$(nvram get asus_device_list | sed 's/2$') MAIN_IP=$(nvram get lan_ipaddr) MAIN_HW_MODEL=$(nvram get modelid) [ -z "$MAIN_HW_MODEL" ] && MAIN_HW_MODEL=$(nvram get productid) [ -f "$CONF_FILE" ] && . "$CONF_FILE" echo -e "${CYAN}==================================================${NC}" echo -e " ROUTER NICKNAME SETUP " echo -e " (Press [Enter] to keep the current name) " echo -e "${CYAN}==================================================${NC}" echo -e "" CURRENT_MAIN_NICK=${MAIN_NICK:-"$MAIN_HW_MODEL"} printf " Main $MAIN_IP [$CURRENT_MAIN_NICK]: " read input_main MAIN_NICK=${input_main:-"$CURRENT_MAIN_NICK"} sed -i '/^MAIN_NICK=/d' "$CONF_FILE" echo "MAIN_NICK=\"$MAIN_NICK\"" >> "$CONF_FILE" if [ -n "$RAW_NODES" ]; then VALID_NODES=$(echo "$RAW_NODES" | awk -F '>' '{print $2 "|" $3}' | sort -t . -k 4,4n) for node in $VALID_NODES; do ALIAS=$(echo "$node" | cut -d'|' -f1) IP=$(echo "$node" | cut -d'|' -f2) CLEAN_IP=$(echo "$IP" | tr '.' '_') eval SAVED_NICK=\$NODE_NICK_$CLEAN_IP CURRENT_DISPLAY=${SAVED_NICK:-"$ALIAS"} printf " Node $IP [$CURRENT_DISPLAY]: " read input_node NEW_NICK=${input_node:-"$CURRENT_DISPLAY"} sed -i "/^NODE_NICK_$CLEAN_IP=/d" "$CONF_FILE" echo "NODE_NICK_$CLEAN_IP=\"$NEW_NICK\"" >> "$CONF_FILE" done fi echo -e "\n${GREEN}[+] Nicknames updated successfully.${NC}" } install_menu() { while true; do clear; check_version; show_menu; read choice case "$choice" in 1) do_install ;; 2) do_uninstall ;; 3) set_temp_unit ;; 4) if [ -f "$CONF_FILE" ]; then set_nicknames [ -f "$REPORT_SCRIPT" ] && sh "$REPORT_SCRIPT" >/dev/null 2>&1 & pause else echo -e "${RED}[!] Please install the report (Option 1) first.${NC}" sleep 2 fi ;; e|E) clear; exit 0 ;; *) echo -e "${RED}Invalid selection.${NC}"; sleep 1 ;; esac done } ###################### # Report Functions # ###################### get_rssi_style() { local r=$1 if [ "$r" -ge -50 ]; then echo "color: #30d158; font-weight: bold;" elif [ "$r" -ge -60 ]; then echo "color: #64d2ff; font-weight: bold;" elif [ "$r" -ge -70 ]; then echo "color: #ffd60a; font-weight: bold;" else echo "color: #ff453a; font-weight: bold;"; fi } get_bars() { local r=$1 if [ "$r" -ge -50 ]; then echo "||||" elif [ "$r" -ge -60 ]; then echo "|||" elif [ "$r" -ge -70 ]; then echo "||" else echo "|"; fi } get_trend() { local mac=$(echo "$1" | tr '[:lower:]' '[:upper:]'); local current=$2 local old=$(grep "$mac" "$HISTORY_DB" | cut -d'|' -f2) echo "$mac|$current" >> "$NEW_HISTORY" if [ -z "$old" ] || [ "$old" -eq 0 ]; then echo ""; return; fi if [ "$current" -gt "$old" ]; then echo "" elif [ "$current" -lt "$old" ]; then echo "" else echo ""; fi } get_name() { local mac=$(echo "$1" | tr '[:lower:]' '[:upper:]') local name="" [ -f "$YAZ_CACHE" ] && name=$(grep -i "$mac" "$YAZ_CACHE" | awk -F'|' '{print $3}' | head -n 1) [ -z "$name" ] && name=$(grep -i "$mac" /var/lib/misc/dnsmasq.leases | awk '{print $4}' | head -n 1) [ -z "$name" ] && [ -f "$ARP_CACHE" ] && name=$(grep -i "$mac" "$ARP_CACHE"|cut -d'|' -f2|head -n 1) [ -z "$name" ] || [ "$name" = "*" ] && name=$(nvram get custom_clientlist | sed 's/' '{print $1}') if [ -z "$name" ] || [ "$name" = "*" ]; then local fuzzy=$(echo "$mac" | cut -d: -f2-5) name=$(grep -i "$fuzzy" "$YAZ_CACHE" | awk -F'|' '{print $3}' | head -n 1) fi [ -z "$name" ] || [ "$name" = "*" ] && name="$mac" echo "$name" } check_new() { local mac=$(echo "$1" | tr '[:lower:]' '[:upper:]') [ ! -f "$KNOWN_DB" ] && touch "$KNOWN_DB" if ! grep -qi "$mac" "$KNOWN_DB"; then echo "$mac" >> "$KNOWN_DB"; echo "new-device-row"; fi } ip_to_num() { echo "$1" | awk -F. '{if(NF==4) printf "%03d%03d%03d%03d", $1,$2,$3,$4; else printf "000000000000";}' ; } get_band_html() { local iface=$1; local width=$2; local model=$3 local w_text=""; [ -n "$width" ] && w_text=" ($width)" local theUILabel="Unknown" # Quad-Band Mapping # Models: GT-BE98(Pro), BQ16, GT-AXE16000, GT-BE25000 if echo "$model" | grep -qiE "BE98|BQ16|AXE16000|BE25000"; then case "$iface" in wl0*) theUILabel="5G" ;; wl1*) echo "$model" | grep -qiE "PRO|BQ16" && theUILabel="6G-1" || theUILabel="5G-2" ;; wl2*) echo "$model" | grep -qiE "PRO|BQ16" && theUILabel="6G-2" || theUILabel="6G" ;; wl3*) theUILabel="2.4G" ;; esac # Tri-Band Mapping (2.4G,5G,6G) # Models: RT-BE96U, RT-BE92U, GT-BE19000, GS-BE18000, GS-BE12000, BT6, BT8, BT10, # RT-AXE7800, GT-AXE11000, ET8, ET9, ET12 elif echo "$model" | grep -qiE "BE96U|BE92U|BE19000|BE18000|BE12000|BT6|BT8|BT10|AXE7800|AXE11000|ET8|ET9|ET12"; then case "$iface" in wl0*|eth1*|eth4*) theUILabel="2.4G" ;; wl1*|eth2*|eth5*) theUILabel="5G" ;; wl2*|eth6*) theUILabel="6G" ;; esac # Tri-Band Mapping (2.4G,5G-1,5G-2) # Models: RT-AX92U, GT6, XT8, XT9, XT12 elif echo "$model" | grep -qiE "AX92U|GT6|XT8|XT9|XT12"; then case "$iface" in wl0*|eth1*|eth4*) theUILabel="2.4G" ;; wl1*|eth2*|eth5*) theUILabel="5G-1" ;; wl2*|eth6*) theUILabel="5G-2" ;; esac # Dual-Band Mapping else case "$iface" in wl0*|eth1*|eth4*|eth6*) theUILabel="2.4G" ;; wl1*|eth2*|eth5*|eth7*) theUILabel="5G" ;; *) theUILabel="Unknown" ;; esac fi # Band UI Renderer local class="" sort="0" case "$theUILabel" in "2.4G") class="text-24"; sort="2.4" ;; "5G"|"5G-1"|"5G-2") class="text-5g"; sort="5" ;; "6G"|"6G-1"|"6G-2") class="text-6g"; sort="6" ;; esac echo "$theUILabel$w_text" } fmt_time() { T=$1; [ -z "$T" ] || ! echo "$T" | grep -qE '^[0-9]+$' && echo "---" && return local pulse=""; [ "$T" -lt 900 ] && pulse="pulse-blue" echo "$T" | awk -v p="$pulse" '{d=int($1/86400); h=int(($1%86400)/3600); m=int(($1%3600)/60); printf "", $1; if(d>0) printf "%02dd %02dh", d, h; else if(h>0) printf "%02dh %02dm", h, m; else printf "00h %02dm", m; printf "";}' } to_f() { local raw_c=$1 [ -z "$raw_c" ] || ! echo "$raw_c" | grep -qE '^-?[0-9]+$' && echo "--" && return if [ "$REPORT_UNIT" = "C" ]; then echo "${raw_c}°C" else echo "$raw_c" | awk '{printf "%.0f°F", ($1 * 1.8) + 32}' fi } get_temp_class() { local temp_str=$1 [ "$temp_str" = "--" ] && echo "val-blue" && return local val=$(echo "$temp_str" | sed 's/[^0-9.]//g') if [ "$REPORT_UNIT" = "C" ]; then awk -v t="$val" 'BEGIN { if(t>75) print "stat-hot"; else if(t>68) print "stat-warm"; else print "val-blue"; }' else awk -v t="$val" 'BEGIN { if(t>167) print "stat-hot"; else if(t>155) print "stat-warm"; else print "val-blue"; }' fi } get_load_class() { local l=$1; [ "$l" = "--" ] && { echo "val-blue"; return; } awk -v l="$l" 'BEGIN { print (l>2.0 ? "stat-hot" : (l>1.0 ? "stat-warm" : "val-blue")) }' } get_mhz_width() { local raw_info="$1" local width="" width=$(echo "$raw_info" | sed -n 's/.*chanspec.*\/\([0-9]*\).*/\1/p') if [ -z "$width" ]; then local hex=$(echo "$raw_info" | grep -o '0x[0-9a-fA-F]*') case "$hex" in 0x10*) width="20" ;; # 2.4G 20MHz 0x11*) width="40" ;; # 2.4G 40MHz 0xd0*) width="20" ;; # 5G 20MHz 0xd1*) width="40" ;; # 5G 40MHz 0xe0*) width="80" ;; # 5G 80MHz 0xe8*|0xe9*) width="160" ;; # 5G/6G 160MHz 0xf0*) width="320" ;; # WiFi 7 320MHz *) width="??" ;; # Unknown esac fi echo "$width" } run_report() { ############### # Main Scan # ############### grep "0x2" /proc/net/arp | awk '{print toupper($4)"|"$1}' > "$ARP_CACHE" [ -f "$YAZ_CLIENTS" ] && awk -F',' '{print toupper($1) "|" $2 "|" $3}' "$YAZ_CLIENTS" > $YAZ_CACHE || > $YAZ_CACHE M_T=$(($(cat /sys/class/thermal/thermal_zone0/temp 2>/dev/null || echo 0) / 1000)) M_TEMP=$(to_f "$M_T") M_LOAD=$(cat /proc/loadavg | awk '{print $1}') MC_TEMP=$(get_temp_class "$M_TEMP") MC_LOAD=$(get_load_class "$M_LOAD") M_UPTIME=$(awk -v s=$(cat /proc/uptime | cut -d. -f1) 'BEGIN {d=int(s/86400); h=int((s%86400)/3600); m=int((s%3600)/60); if(d>0) printf "%dd %dh %dm", d, h, m; else if(h>0) printf "%dh %dm", h, m; else printf "%dm", m}') M_BOOT=$(date -d @$(( $(date +%s) - $(cut -d. -f1 /proc/uptime) )) "$D_FMT") MAIN_PFX=$(nvram get lan_hwaddr | cut -c 1-14 | tr '[:lower:]' '[:upper:]') NODE_PFX=$(nvram get asus_device_list | sed 's/' '{print $1}' | cut -c 1-14 | tr '[:lower:]' '[:upper:]') ROUTER_IP=$(nvram get lan_ipaddr) DEVICE_LIST=$(nvram get cfg_device_list) M_ALIAS=$(echo "$DEVICE_LIST" | sed 's/$ROUTER_IP>" | awk -F'>' '{print $1}') M_NAME="${MAIN_NICK:-${M_ALIAS:-"Main Router"}}" [ ${#M_NAME} -gt 25 ] && M_NAME="${M_NAME:0:25}" MAIN_LABEL="$M_NAME (MAIN)" RSSI_UNIT="ᵈᴮᵐ" MBPS_UNIT="ᵐᵇᵖˢ" MHZ_UNIT="ᵐʰᶻ" T_EXC=0; T_GOOD=0; T_FAIR=0; T_POOR=0; M_TOTAL=0; N_TOTAL=0 for iface in $(ifconfig -a | grep -oE "wl[0-9](\.[0-9])?|eth[1-7]"); do case "$iface" in wl0.0|wl1.0|wl2.0|wl3.0) continue ;; esac case "$iface" in eth1|eth4|eth6) [ -n "$(nvram get wl3_ssid)" ] && data_iface="wl3" || { [ -n "$(nvram get wl2_ssid)" ] && data_iface="wl2" || data_iface="wl0"; } ;; eth2|eth5|eth7) data_iface="wl1" ;; *) data_iface="$iface" ;; esac SNAME=$(nvram get "${data_iface}_ssid") [ -z "$SNAME" ] && SNAME=$(nvram get "${iface%.*}_ssid") if echo "$SNAME" | grep -qE '^[0-9A-Fa-f]{16,}$'; then continue; fi for mac in $(wl -i "$iface" assoclist 2>/dev/null | awk '{print $2}'); do m_live=$(echo "$mac" | tr '[:lower:]' '[:upper:]') m_prefix=$(echo "$m_live" | cut -c 1-14) if echo "$MAIN_PFX $NODE_PFX" | grep -q "$m_prefix"; then continue; fi yaz_entry=$(grep -i "^$m_live|" "$YAZ_CACHE" | head -n 1) [ -z "$yaz_entry" ] && yaz_entry=$(grep -i "$(echo "$m_live" | cut -d: -f2-5)" "$YAZ_CACHE" | grep -vE '[]r]' | head -n 1) [ -n "$yaz_entry" ] && { m_up=$(echo "$yaz_entry" | cut -d'|' -f1 | tr '[:lower:]' '[:upper:]'); ip=$(echo "$yaz_entry" | cut -d'|' -f2); name=$(echo "$yaz_entry" | cut -d'|' -f3); } || \ { m_up="$m_live"; name=$(get_name "$m_up"); ip=$(grep -ih "$m_up" "$ARP_CACHE" "$YAZ_CACHE" | cut -d'|' -f2 | head -n 1); } [ -z "$ip" ] && ip="---" || ip=$(printf "%s.%03d" "${ip%.*}" "${ip##*.}") { [ -z "$name" ] || [ "$name" = "*" ]; } && name="$m_up" rssi=$(wl -i "$iface" rssi "$mac" 2>/dev/null | awk '{print $1}') ! echo "$rssi" | grep -qE '^-[0-9]+$' && continue [ "$rssi" -ge -20 ] || [ "$rssi" -le -100 ] || grep -qi "$m_up" "$SEEN_MACS" && continue echo "$m_up" | grep -qE '^([0-9A-F]{2}:){5}[0-9A-F]{2}$' && echo "$m_up" >> "$SEEN_MACS" raw_info=$(wl -i "$iface" sta_info "$mac" 2>/dev/null) rx_raw=$(echo "$raw_info" | grep "rate of last rx pkt" | awk '{print $6/1000}') tx_raw=$(echo "$raw_info" | grep "rate of last tx pkt" | awk -F': ' '{print $2}' | awk '{print $1/1000}') max_raw=$(echo "$raw_info" | grep "Max Rate =" | awk '{print $4}') mhz_width=$(get_mhz_width "$raw_info") [ -z "$rx_raw" ] || [ "$rx_raw" = "0" ] && rx_disp="?" || rx_disp="${rx_raw%.*}" [ -z "$tx_raw" ] || [ "$tx_raw" = "0" ] && tx_disp="${max_raw:-?}" || tx_disp="${tx_raw%.*}" l_rate_disp="${rx_disp} / ${tx_disp}" V1=$(echo "$rx_disp" | tr -dc '0-9'); V2=$(echo "$tx_disp" | tr -dc '0-9') [ -n "$V1" ] && [ -n "$V2" ] && [ "$V1" -gt "$V2" ] 2>/dev/null && { T=$rx_disp; rx_disp=$tx_disp; tx_disp=$T; l_rate_disp="$rx_disp / $tx_disp"; } [ "$rx_disp" = "?" ] && [ "$tx_disp" = "?" ] && l_rate_disp="---" l_rate_val=${tx_disp:-0} is_new=$(check_new "$m_up") trend=$(get_trend "$m_up" "$rssi") bars=$(get_bars "$rssi") rssi_style=$(get_rssi_style "$rssi") uptime=$(echo "$raw_info" | grep 'in network' | awk '{print $3}') [ ${#name} -gt 20 ] && name="${name:0:20}" display_ssid="$SNAME" [ ${#display_ssid} -gt 15 ] && display_ssid="${display_ssid:0:15}" ip_s=$(ip_to_num "$ip") band_td=$(get_band_html "$iface" "$mhz_width" "$M_ALIAS") if [ "$rssi" -ge -50 ]; then T_EXC=$((T_EXC+1)); elif [ "$rssi" -ge -60 ]; then T_GOOD=$((T_GOOD+1)); elif [ "$rssi" -ge -70 ]; then T_FAIR=$((T_FAIR+1)); else T_POOR=$((T_POOR+1)); fi ROW_STR="$name$m_up$ip$bars $rssi $trend$l_rate_disp$display_ssid$iface$band_td$(fmt_time "$uptime")" echo "$ROW_STR" >> $MAIN_ROWS; echo "$ROW_STR" >> $ALL_ROWS M_TOTAL=$((M_TOTAL + 1)) done done CONSOLIDATED_T="${M_TEMP}" CONSOLIDATED_L="${M_LOAD}" CONSOLIDATED_U="${M_UPTIME}" CONSOLIDATED_B="${M_BOOT}" #################### # Node Scan Loop # #################### [ -n "$SSH_NODES" ] && TARGET_LIST="$SSH_NODES" || TARGET_LIST=$(nvram get asus_device_list | sed 's/2$' | awk -F '>' '{print $1"|"$2"|"$3}' | sort -t '|' -k 1,1 | awk -F '|' '{print $2"|"$3}') for line in $TARGET_LIST; do ALIAS="${line%|*}"; IP="${line#*|}"; done SSH_PORT=$(nvram get sshd_port); SSH_PORT=${SSH_PORT:-22} NODE_WIDTH_LOGIC="W=\$(echo \"\$RAW\" | sed -n 's/.*chanspec.*\\/\\([0-9]*\\).*/\\1/p') if [ -z \"\$W\" ]; then HEX=\$(echo \"\$RAW\" | grep -o '0x[0-9a-fA-F]*') case \"\$HEX\" in 0x10*|0xd0*) W=\"20\" ;; 0x11*|0xd1*) W=\"40\" ;; 0xe0*) W=\"80\" ;; 0xe8*|0xe9*) W=\"160\" ;; 0xf*) W=\"320\" ;; *) W=\"??\" ;; esac fi" NODE_USER=$(nvram get http_username) NODE_DATA=$(nvram get asus_device_list | sed 's/2$' | awk -F '>' '{print $2 "|" $3}' | sort -t . -k 4,4n) NODE_COUNT_TOTAL=$(echo "$NODE_DATA" | grep -v "^$" | wc -l) [ "$NODE_COUNT_TOTAL" -gt 1 ] && N_SUFFIX="(NODES)" || N_SUFFIX="(NODE)" NODE_COLORS="#64d2ff #30d158 #ffd60a #bf40bf #ff9500 #ff453a"; PIPE=" | " N_NAMES=""; N_TEMPS=""; N_LOADS=""; N_BOOTS=""; N_UPTIMES=""; N_SPLIT_COUNTS=""; COLOR_IDX=0; ACTIVE_NODES=0 for line in $TARGET_LIST; do NODE_OUT="" IP=$(echo "$line" | cut -d'|' -f2) ALIAS=$(echo "$line" | cut -d'|' -f1) [ -z "$IP" ] && continue CLEAN_IP=$(echo "$IP" | tr '.' '_'); eval CUSTOM_NICK=\$NODE_NICK_$CLEAN_IP NODE_DISPLAY_NAME="${CUSTOM_NICK:-${ALIAS:-$IP}}" [ ${#NODE_DISPLAY_NAME} -gt 25 ] && NODE_DISPLAY_NAME="${NODE_DISPLAY_NAME:0:25}" NODE_OUT=$(/usr/bin/ssh -p "$SSH_PORT" -i "$SSH_KEY" -o StrictHostKeyChecking=no "${NODE_USER}@${IP}" " UP_SEC=\$(cut -d. -f1 /proc/uptime) F_UP=\$(awk -v s=\"\$UP_SEC\" 'BEGIN {d=int(s/86400); h=int((s%86400)/3600); m=int((s%3600)/60); if(d>0) printf \"%dd %dh %dm\", d, h, m; else if(h>0) printf \"%dh %dm\", h, m; else printf \"%dm\", m}') NODE_COUNT=0 for iface in \$(ifconfig -a | grep -oE \"wl[0-9](\.[0-9])?\"); do case \"\$iface\" in wl0.0|wl1.0|wl2.0|wl3.0) continue ;; esac SN=\$(nvram get \"\${iface}_ssid\"); [ -z \"\$SN\" ] && SN=\$(nvram get \"\${iface%.*}_ssid\") if echo \"\$SN\" | grep -qE '^[0-9A-Fa-f]{16,}$'; then continue; fi for mac in \$(wl -i \"\$iface\" assoclist 2>/dev/null | awk '{print \$2}'); do RAW=\$(wl -i \"\$iface\" sta_info \"\$mac\" 2>/dev/null) RSSI=\$(wl -i \"\$iface\" rssi \"\$mac\" 2>/dev/null | awk '{print \$1}') $NODE_WIDTH_LOGIC RX=\$(echo \"\$RAW\" | grep \"rate of last rx pkt\" | awk '{print \$6/1000}') TX=\$(echo \"\$RAW\" | grep \"rate of last tx pkt\" | awk -F': ' '{print \$2}' | awk '{print \$1/1000}') MX=\$(echo \"\$RAW\" | grep \"Max Rate =\" | awk '{print \$4}') HB=\$(wl -i \"\$iface\" band | awk '{print \$1}') RXD=\$(echo \"\$RX\" | awk '{if (\$1==0) print \"?\"; else printf \"%.0f\", \$1}') TXD=\$(echo \"\$TX\" | awk -v m=\"\$MX\" '{if (\$1==0) print m; else printf \"%.0f\", \$1}') [ \"\$RXD\" = \"?\" ] && [ \"\$TXD\" = \"?\" ] && LRD=\"\${MX:-?}\" || LRD=\"\${RXD} / \${TXD}\" V1=\$(echo \"\$RXD\" | tr -dc '0-9'); V2=\$(echo \"\$TXD\" | tr -dc '0-9') [ -n \"\$V1\" ] && [ -n \"\$V2\" ] && [ \"\$V1\" -gt \"\$V2\" ] 2>/dev/null && { T=\$RXD; RXD=\$TXD; TXD=\$T; LRD=\"\$RXD / \$TXD\"; } echo \"DATA|\$mac|\$RSSI|\$iface|\$(echo \"\$RAW\" | grep \"in network\" | awk '{print \$3}')|\$SN|\$TX|\$LRD|\$W|\$HB\" NODE_COUNT=\$((NODE_COUNT + 1)) done done echo \"TEMP|\$(cat /sys/class/thermal/thermal_zone0/temp 2>/dev/null | cut -c1-2)\" echo \"LOAD|\$(cat /proc/loadavg | awk '{print \$1}')\" echo \"UPTIME_VAL|\$F_UP\"; echo \"UPTIME_RAW|\$UP_SEC\"; echo \"COUNT|\$NODE_COUNT\" " 2>/dev/null) if [ -n "$NODE_OUT" ]; then ACTIVE_NODES=$((ACTIVE_NODES + 1)); COLOR_IDX=$((COLOR_IDX + 1)) CUR_COLOR=$(echo $NODE_COLORS | cut -d' ' -f$((COLOR_IDX))) [ -z "$CUR_COLOR" ] && CUR_COLOR="#ffffff" STAR_HTML="$ACTIVE_NODES" NODE_BRAND="${NODE_DISPLAY_NAME}$ACTIVE_NODES" [ -z "$N_NAMES" ] && N_NAMES="$NODE_BRAND" || N_NAMES="$N_NAMES$PIPE$NODE_BRAND" N_TEMP_RAW=$(echo "$NODE_OUT" | grep "TEMP|" | cut -d'|' -f2) [ ${#N_TEMP_RAW} -gt 3 ] && N_TEMP_RAW=$((N_TEMP_RAW / 1000)) N_TEMP=$(to_f "$N_TEMP_RAW") N_LOAD=$(echo "$NODE_OUT" | grep "LOAD|" | cut -d'|' -f2) NC_TEMP=$(get_temp_class "$N_TEMP") NC_LOAD=$(get_load_class "$N_LOAD") N_UPTIME_RAW=$(echo "$NODE_OUT" | grep "UPTIME_RAW|" | cut -d'|' -f2) N_UPTIME=$(echo "$NODE_OUT" | grep "UPTIME_VAL|" | cut -d'|' -f2) N_BOOT=$(date -d @$(( $(date +%s) - ${N_UPTIME_RAW:-0} )) "$D_FMT") CONSOLIDATED_T="$CONSOLIDATED_T | ${N_TEMP}" CONSOLIDATED_L="$CONSOLIDATED_L | ${N_LOAD}" CONSOLIDATED_U="$CONSOLIDATED_U | ${N_UPTIME}" CONSOLIDATED_B="$CONSOLIDATED_B | ${N_BOOT}" N_TEMPS="${N_TEMPS}${N_TEMPS:+$PIPE}$N_TEMP" N_LOADS="${N_LOADS}${N_LOADS:+$PIPE}$N_LOAD" N_UPTIMES="${N_UPTIMES}${N_UPTIMES:+$PIPE}$N_UPTIME" N_BOOTS="${N_BOOTS}${N_BOOTS:+$PIPE}$N_BOOT" NODE_DISPLAY_COUNT=0 while read -r dline; do [ -z "$dline" ] && continue m_live=$(echo "$dline" | cut -d'|' -f2 | tr '[:lower:]' '[:upper:]') m_prefix=$(echo "$m_live" | cut -c 1-14) { echo "$MAIN_PFX $NODE_PFX" | grep -q "$m_prefix" || grep -qi "$m_live" "$SEEN_MACS"; } && continue yaz_entry=$(grep -i "^$m_live|" "$YAZ_CACHE" | head -n 1) [ -z "$yaz_entry" ] && yaz_entry=$(grep -i "$(echo "$m_live" | cut -d: -f2-5)" "$YAZ_CACHE" | grep -vE '[]r]' | head -n 1) [ -n "$yaz_entry" ] && { m_up=$(echo "$yaz_entry" | cut -d'|' -f1 | tr '[:lower:]' '[:upper:]'); n_ip=$(echo "$yaz_entry" | cut -d'|' -f2); n_name=$(echo "$yaz_entry" | cut -d'|' -f3); } || \ { m_up="$m_live"; n_name=$(get_name "$m_up"); n_ip=$(grep -ih "$m_up" "$ARP_CACHE" "$YAZ_CACHE" | cut -d'|' -f2 | head -n 1); } [ -z "$n_ip" ] && n_ip="---" || n_ip=$(printf "%s.%03d" "${n_ip%.*}" "${n_ip##*.}") { [ -z "$n_name" ] || [ "$n_name" = "*" ]; } && n_name="$m_up" grep -qi "$m_up" "$SEEN_MACS" && continue echo "$m_up" | grep -qE '^([0-9A-F]{2}:){5}[0-9A-F]{2}$' && echo "$m_up" >> "$SEEN_MACS" N_TOTAL=$((N_TOTAL + 1)) NODE_DISPLAY_COUNT=$((NODE_DISPLAY_COUNT + 1)) r_raw=$(echo "$dline" | cut -d'|' -f3) if [ "$r_raw" -ge -50 ]; then echo "EXC" >> "$Q_RELAY" elif [ "$r_raw" -ge -60 ]; then echo "GOOD" >> "$Q_RELAY" elif [ "$r_raw" -ge -70 ]; then echo "FAIR" >> "$Q_RELAY" else echo "POOR" >> "$Q_RELAY"; fi i_raw=$(echo "$dline" | cut -d'|' -f4) u_raw=$(echo "$dline" | cut -d'|' -f5) s_name=$(echo "$dline" | cut -d'|' -f6) display_s_name="$s_name" [ ${#display_s_name} -gt 15 ] && display_s_name="${display_s_name:0:15}" l_rate_val=$(echo "$dline" | cut -d'|' -f7) l_rate_disp_n=$(echo "$dline" | cut -d'|' -f8) w_raw=$(echo "$dline" | cut -d'|' -f9) hb_raw=$(echo "$dline" | cut -d'|' -f10) is_new=$(check_new "$m_up") trend=$(get_trend "$m_up" "$r_raw") bars_n=$(get_bars "$r_raw") rssi_style_n=$(get_rssi_style "$r_raw") [ ${#n_name} -gt 20 ] && n_name="${n_name:0:20}" ip_ns=$(ip_to_num "$n_ip") band_td_n=$(get_band_html "$i_raw" "$w_raw" "$ALIAS") N_ROW="$n_name$STAR_HTML$m_up$n_ip$bars_n $r_raw $trend$l_rate_disp_n$display_s_name$i_raw$band_td_n$(fmt_time "$u_raw")" echo "$N_ROW" >> $NODE_ROWS; echo "$N_ROW" >> $ALL_ROWS done < $OUT_FILE cat <> $OUT_FILE ASUS Wireless Router $M_NAME - Wireless Report
 

WIRELESS REPORT

$HOVER_TEXT
Total Wireless Devices: $GRAND_TOTAL
Auto:
$MAIN_LABEL
Updated: $CUR_TIME
Temp: $M_TEMP • Load: $M_LOAD • Devices: $M_TOTAL
$(cat $MAIN_ROWS)
HOSTNAME IP ADDRESS RSSI RX/TX SSID BAND UPTIME
Uptime: $M_UPTIME • Reboot: $M_BOOT
Excellent: $T_EXC
Good: $T_GOOD
Fair: $T_FAIR
Poor: $T_POOR
$N_NAMES $N_SUFFIX
Updated: $CUR_TIME
Temp: ${N_TEMPS:-0} • Load: ${N_LOADS:-0} • Devices: $N_TOTAL —› $N_SPLIT_COUNTS
$(cat $NODE_ROWS)
HOSTNAME IP ADDRESS RSSI RX/TX SSID BAND UPTIME
$( [ -n "$N_UPTIMES" ] && echo "Uptime: $N_UPTIMES • Reboot: $N_BOOTS" || echo "Offline" )
$BRAND_LINE_ALL
Updated: $CUR_TIME
Temp: $CONSOLIDATED_T • Load: $CONSOLIDATED_L • $FULL_DEVICE_BREAKDOWN
$(cat $ALL_ROWS)
HOSTNAME IP ADDRESS RSSI RX/TX SSID BAND UPTIME
Uptime: $CONSOLIDATED_U • Reboot: $CONSOLIDATED_B
HTML rm -f $SEEN_MACS $ARP_CACHE $YAZ_CACHE $MAIN_ROWS $NODE_ROWS $ALL_ROWS $Q_RELAY } case "$1" in install) # Install/Uninstall options # Command: wirelessreport install install_menu ;; inject) # Called by services-start to mount the tab # Command: wirelessreport inject inject_menu ;; amtmupdate) # Called by AMTM for autoupdates # Command: wirelessreport amtmupdate shift ScriptUpdateFromAMTM "$@" exit "$?" ;; *) # Run (Scans) # Runs if no argument is provided run_report ;; esac