From 9d3e5ae97e5aa230158036eddbbe256192227f49 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Tue, 2 Dec 2025 18:39:35 -0500 Subject: [PATCH 01/62] Create rtrmon-debug.sh --- rtrmon-debug.sh | 6631 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 6631 insertions(+) create mode 100644 rtrmon-debug.sh diff --git a/rtrmon-debug.sh b/rtrmon-debug.sh new file mode 100644 index 0000000..9f0f65f --- /dev/null +++ b/rtrmon-debug.sh @@ -0,0 +1,6631 @@ +#!/bin/sh + +# RTRMON - Asus-Merlin Router Monitor by Viktor Jaep, 2022-2025 +# +# RTRMON is a shell script that provides near-realtime stats about your Asus-Merlin firmware router. Instead of having to +# find this information on various different screens or apps, this tool was built to bring all this info together in one +# stat dashboard. Having a 'system' dashboard showing current CPU, Memory, Disk and Network stats would compiment other +# dashboard-like scripts greatly (like RTRMON), sitting side-by-side in their own SSH windows to give you everything +# you need to know that's happening on your network with a glance at your screen. +# +# Capabilities have been added to give a full view of your router's CPU, Memory, Disk, NVRAM, Swap file, WAN, LAN, Wi-FI, +# IP4/6 addresses, CPU/Antenna Temps, in addition to having incorporated the Ookla Speedtest Binaries for you to run an on +# -demand Speedtest with the press of a button. New supported models are continually being added as @RMerlin adds support +# for them with his own firmware. +# +# Please use the 'sh rtrmon.sh -setup' command to configure the necessary parameters that match your environment the best! +# +# Last Modified: 2025-Nov-16 +########################################################################################################################### + +#Preferred standard router binaries path +export PATH="/sbin:/bin:/usr/sbin:/usr/bin:$PATH" + +# ------------------------------------------------------------------------------------------------------------------------- +# System Variables (Do not change beyond this point or this may change the programs ability to function correctly) +# ------------------------------------------------------------------------------------------------------------------------- +Version="2.2.3" +Beta=0 +ScreenshotMode=0 +LOGFILE="/jffs/addons/rtrmon.d/rtrmon.log" # Logfile path/name that captures important date/time events - change +APPPATH="/jffs/scripts/rtrmon.sh" # Path to the location of rtrmon.sh +CFGPATH="/jffs/addons/rtrmon.d/rtrmon.cfg" # Path to the location of rtrmon.cfg +DLVERPATH="/jffs/addons/rtrmon.d/version.txt" # Path to downloaded version from the source repository +OOKLAPATH="/jffs/addons/rtrmon.d/speedtest" # Path to Ookla speedtest binary +SPDRESPATH="/jffs/addons/rtrmon.d/results.txt" # Path to latest speedtest results +IFLIST="/jffs/addons/rtrmon.d/interfaces.txt" # Path to the Interface List +DIAGRESPATH="/jffs/addons/rtrmon.d/diagres.txt" # Path to the network diagnostics results +NMAPWANRESPATH="/jffs/addons/rtrmon.d/nwanres.txt" # Path to the nmap WAN open TCP port results +NMAPLANRESPATH="/jffs/addons/rtrmon.d/nlanres.txt" # Path to the nmap LAN open TCP port results +NMAPUWANRESPATH="/jffs/addons/rtrmon.d/nuwanres.txt" # Path to the nmap WAN open UDP port results +NMAPULANRESPATH="/jffs/addons/rtrmon.d/nulanres.txt" # Path to the nmap LAN open UDP port results +INITIALBOOT=0 +CHANGES=0 +LOGSIZE=2000 +Interval=10 +MaxSpeedInet=1000 +MaxSpeedInetUL=50 +MaxSpeedLAN=1000 +MaxSpeed24Ghz=450 +MaxSpeed5Ghz=780 +MaxSpeed6Ghz=920 +TempUnits="C" +Speedtst=0 +WANOverride="Auto" +WAN0AltModes=0 +VPNSite2Site=0 +PSView="TCP" +NCView="WAN" +spdtestsvrID=0 +autorotate=0 +autorotateindicator="OFF" +QueueSpdTest=0 +QueueNetworkDiag=0 +QueueNetworkConn=0 +QueueVPNSlot1=0 +QueueVPNSlot2=0 +QueueVPNSlot3=0 +QueueVPNSlot4=0 +QueueVPNSlot5=0 +QueueWGlot1=0 +QueueWGSlot2=0 +QueueWGSlot3=0 +QueueWGSlot4=0 +QueueWGSlot5=0 +vpn1slot=0 +vpn2slot=0 +vpn3slot=0 +vpn4slot=0 +vpn5slot=0 +VPNState=0 +VPN2State=0 +VPN3State=0 +VPN4State=0 +VPN5State=0 +vpn1city="Unknown" +vpn2city="Unknown" +vpn3city="Unknown" +vpn4city="Unknown" +vpn5city="Unknown" +vpn1ip="0.0.0.0" +vpn2ip="0.0.0.0" +vpn3ip="0.0.0.0" +vpn4ip="0.0.0.0" +vpn5ip="0.0.0.0" +vpn1on="False" +vpn2on="False" +vpn3on="False" +vpn4on="False" +vpn5on="False" +wg1on="False" +wg2on="False" +wg3on="False" +wg4on="False" +wg5on="False" +FromUI=0 +NextPage=1 +memused1=0 +memfree1=0 +memshrd1=0 +membuff1=0 +memcach1=0 +memused2=0 +memfree2=0 +memshrd2=0 +membuff2=0 +memcach2=0 +cpuusr1=0 +cpusys1=0 +cpunice1=0 +cpuidle1=0 +cpuirq1=0 +displaycpuusr1=0 +displaycpusys1=0 +displaycpunice1=0 +displaycpuidle1=0 +displaycpuirq1=0 +w24udsched="Scheduler Inactive" +w5udsched="Scheduler Inactive" +w52udsched="Scheduler Inactive" +w6udsched="Scheduler Inactive" +w62udsched="Scheduler Inactive" +w24updown="UP" +w5updown="UP" +w52updown="UP" +w6updown="UP" +w62updown="UP" +SortbyOpt="Name" + +##-------------------------------------## +## Added by Martinski W. [2024-Nov-04] ## +##-------------------------------------## +timerReset=0 +timeoutcmd="" # For "timeout" cmd for "nvram" calls # +timeoutsec="" # For "timeout" cmd for "nvram" calls # +timeoutlng="" # For "timeout" cmd for "nvram" calls # +hideoptions=1 # Hide/Show menu options flag # +prevHideOpts=X # Avoid redisplaying the options menu unnecessarily too often # +prevSortByOpt=X # Avoid resetting the timer loop unnecessarily too often # +bootInterval=10 # For "Boot Sequence" loop # +LAN_HostName="" +readonly gSavedSTTY="$(stty -g)" + +##-------------------------------------## +## Added by Martinski W. [2024-Nov-05] ## +##-------------------------------------## +pausedTimerEnabled=false # To pause/resume main loop timer cycle # +pausedTimerDispStr="" +readonly pausedTimerMsgStr=" [** PAUSED **] " +readonly pausedTimerMsgLen="${#pausedTimerMsgStr}" + +# Color variables +CBlack="\e[1;30m" +InvBlack="\e[1;40m" +CRed="\e[1;31m" +InvRed="\e[1;41m" +CGreen="\e[1;32m" +InvGreen="\e[1;42m" +CDkGray="\e[1;90m" +InvDkGray="\e[1;100m" +InvLtGray="\e[1;47m" +CYellow="\e[1;33m" +InvYellow="\e[1;43m" +CBlue="\e[1;34m" +InvBlue="\e[1;44m" +CMagenta="\e[1;35m" +CCyan="\e[1;36m" +InvCyan="\e[1;46m" +CWhite="\e[1;37m" +InvWhite="\e[1;107m" +CClear="\e[0m" + +# ------------------------------------------------------------------------------------------------------------------------- +# Functions +# ------------------------------------------------------------------------------------------------------------------------- + +#Shows the version bar formatted for build and date/time with TZ spacing# +##----------------------------------------## +## Modified by Martinski W. [2024-Nov-04] ## +##----------------------------------------## +showheader() +{ + if [ "$hideoptions" = "0" ] && [ "$hideoptions" != "$prevHideOpts" ] + then displayopsmenu ; fi + + timerReset=0 + prevHideOpts="$hideoptions" + prevSortByOpt="$SortbyOpt" + + tzone="$(date +%Z)" + tzonechars="${#tzone}" + + if [ "$tzonechars" = "1" ]; then tzspaces=" "; + elif [ "$tzonechars" = "2" ]; then tzspaces=" "; + elif [ "$tzonechars" = "3" ]; then tzspaces=" "; + elif [ "$tzonechars" = "4" ]; then tzspaces=" "; + elif [ "$tzonechars" = "5" ]; then tzspaces=" "; fi + + #Display RTRMON client header + echo -en "${InvGreen} ${InvDkGray}${CWhite} RTRMON - v" + printf "%-8s" $Version + echo -e " ${CGreen}(S)${CWhite}how/${CGreen}(H)${CWhite}ide Operations Menu ${InvDkGray} $tzspaces$(date) ${CClear}" +} + +# ------------------------------------------------------------------------------------------------------------------------- +# Displays the "Operations Menu" on top of screen. + +##----------------------------------------## +## Modified by Martinski W. [2024-Nov-02] ## +##----------------------------------------## +displayopsmenu() +{ + amtmdisp="${CDkGray}[n/a] " + + echo -e "${InvGreen} ${InvDkGray}${CWhite} Operations Menu ${CClear}" + if [ "$vpn1on" == "True" ] || [ "$vpn2on" == "True" ] || [ "$vpn3on" == "True" ] || [ "$vpn4on" == "True" ] || [ "$vpn5on" == "True" ] + then + echo -e "${InvGreen} ${CClear} Speedtest ${CGreen}(I)${CClear} WAN / VPN 1:${CGreen}(1)${CClear} 2:${CGreen}(2)${CClear} 3:${CGreen}(3)${CClear} 4:${CGreen}(4)${CClear} 5:${CGreen}(5)${CClear} ${InvGreen} ${CClear} ${CGreen}(M)${CClear}ain Setup Menu / Configuration Menu${CClear}" + else + echo -e "${InvGreen} ${CClear} Speedtest ${CGreen}(I)${CClear} WAN ${CDkGray}/ VPN 1:(1) 2:(2) 3:(3) 4:(4) 5:(5)${CClear} ${InvGreen} ${CClear} ${CGreen}(M)${CClear}ain Setup Menu / Configuration Menu${CClear}" + fi + if [ "$wg1on" == "True" ] || [ "$wg2on" == "True" ] || [ "$wg3on" == "True" ] || [ "$wg4on" == "True" ] || [ "$wg5on" == "True" ] + then + echo -e "${InvGreen} ${CClear} Speedtest Wireguard 1:${CGreen}(6)${CClear} 2:${CGreen}(7)${CClear} 3:${CGreen}(8)${CClear} 4:${CGreen}(9)${CClear} 5:${CGreen}(0)${CClear} ${InvGreen} ${CClear} L${CGreen}(O)${CClear}g Viewer / Trim Log Size (rows): ${CGreen}$LOGSIZE${CClear}" + else + echo -e "${InvGreen} ${CClear} ${CDkGray}Speedtest Wireguard 1:(6) 2:(7) 3:(8) 4:(9) 5:(0)${CClear} ${InvGreen} ${CClear} L${CGreen}(O)${CClear}g Viewer / Trim Log Size (rows): ${CGreen}$LOGSIZE${CClear}" + fi + echo -e "${InvGreen} ${CClear} Run Router Network ${CGreen}(D)${CClear}iagnostics ${InvGreen} ${CClear} ${CGreen}(N)${CClear}ext Page / ${CGreen}(P)${CClear}revious Page: ${CGreen}($NextPage/7)${CClear}" + echo -e "${InvGreen} ${CClear} Refresh ${CGreen}(C)${CClear}urrent Network Statistics ${InvGreen} ${CClear} Auto ${CGreen}(R)${CClear}otate Pages Option: ${CGreen}$autorotateindicator${CClear}" + echo -e "${InvGreen} ${CClear} View ${CGreen}(W)${CClear}AN / ${CGreen}(L)${CClear}AN / ${CGreen}(V)${CClear}PN / W${CGreen}(G)${CClear} Stats ${InvGreen} ${CClear} Router Model/FW: ${CGreen}${RouterModel} | ${FWBUILD}${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo "" +} + +##-------------------------------------## +## Added by Martinski W. [2024-Nov-02] ## +##-------------------------------------## +_ConsumeKeypressBuffer_() +{ + local savedSettings + local keyPress='' prevTimeSec + savedSettings="$(stty -g)" + prevTimeSec="$(date +%s)" + read -rs -n1000 -t 1 keyPress < "$(tty 0>&2)" + while [ "$(date +%s)" -lt "$((prevTimeSec + 1))" ] + do + stty -echo -icanon min 0 time 1 + cat - > /dev/null + done + stty "$savedSettings" +} + +##-------------------------------------## +## Added by Martinski W. [2024-Nov-02] ## +##-------------------------------------## +_IgnoreKeypresses_() +{ + if [ $# -eq 0 ] || [ -z "$1" ] + then return 1 ; fi + case "$1" in + ON) stty -echo ;; + OFF) stty "$gSavedSTTY" ; stty echo ;; + esac +} + +# ------------------------------------------------------------------------------------------------------------------------- +# LogoNM displays the RTRMON script name in a cool ASCII font that fades in +##----------------------------------------## +## Modified by Martinski W. [2024-Nov-02] ## +##----------------------------------------## +logoNM () +{ + clear + echo "" + echo "" + echo "" + echo -e "${CDkGray} ____ __________ __ _______ _ __" + echo -e " / __ \/_ __/ __ \/ |/ / __ \/ | / /" + echo -e " / /_/ / / / / /_/ / /|_/ / / / / |/ /" + echo -e " / _, _/ / / / _, _/ / / / /_/ / /| /" + echo -e " /_/ |_| /_/ /_/ |_/_/ /_/\____/_/ |_/ v$Version" + echo "" + echo "" + printf "\r ${CGreen} [ INITIALIZING ] ${CClear}" + _ConsumeKeypressBuffer_ + clear + echo "" + echo "" + echo "" + echo -e "${CYellow} ____ __________ __ _______ _ __" + echo -e " / __ \/_ __/ __ \/ |/ / __ \/ | / /" + echo -e " / /_/ / / / / /_/ / /|_/ / / / / |/ /" + echo -e " / _, _/ / / / _, _/ / / / /_/ / /| /" + echo -e " /_/ |_| /_/ /_/ |_/_/ /_/\____/_/ |_/ v$Version" + echo "" + echo "" +} + +# ------------------------------------------------------------------------------------------------------------------------- +# logoNMexit displays the RTRMON script name in a cool ASCII font that fades out + +logoNMexit () { + clear + echo "" + echo "" + echo "" + echo -e "${CYellow} ____ __________ __ _______ _ __" + echo -e " / __ \/_ __/ __ \/ |/ / __ \/ | / /" + echo -e " / /_/ / / / / /_/ / /|_/ / / / / |/ /" + echo -e " / _, _/ / / / _, _/ / / / /_/ / /| /" + echo -e " /_/ |_| /_/ /_/ |_/_/ /_/\____/_/ |_/ v$Version" + echo "" + echo "" + printf "\r ${CGreen} [ SHUTTING DOWN ] ${CClear}" + sleep 1 + clear + echo "" + echo "" + echo "" + echo -e "${CDkGray} ____ __________ __ _______ _ __" + echo -e " / __ \/_ __/ __ \/ |/ / __ \/ | / /" + echo -e " / /_/ / / / / /_/ / /|_/ / / / / |/ /" + echo -e " / _, _/ / / / _, _/ / / / /_/ / /| /" + echo -e " /_/ |_| /_/ /_/ |_/_/ /_/\____/_/ |_/ v$Version" + echo "" + echo "" + printf "\r ${CGreen} [ SHUTTING DOWN ] ${CClear}" + sleep 1 + printf "\r ${CDkGray} [ GOODBYE... ] ${CClear}\n\n" + sleep 1 +} + +##-------------------------------------## +## Added by Martinski W. [2024-Nov-02] ## +##-------------------------------------## +_PressAnyKeyToContinue_() +{ printf "\nPress any key to continue..." ; read -rsn1 anykey ; echo ; } + +# ------------------------------------------------------------------------------------------------------------------------- +# promptyn takes input for Y/N questions + +promptyn () { # No defaults, just y or n + while true; do + read -p '[y/n]? ' YESNO + case "$YESNO" in + [Yy]* ) return 0 ;; + [Nn]* ) return 1 ;; + * ) echo -e "\nPlease answer y or n.";; + esac + done +} + +# ------------------------------------------------------------------------------------------------------------------------- +# Spinner provides a small spinning indicator on the screen to show script activity + +spinner() +{ + spins="$1" + + spin=0 + totalspins="$((spins / 4))" + while [ "$spin" -le "$totalspins" ] + do + for spinchar in / - \\ \| + do + printf "\r$spinchar" + sleep 1 + done + spin="$((spin+1))" + done + + printf "\r" +} + +# ------------------------------------------------------------------------------------------------------------------------- +# Preparebar and Progressbar is a script that provides a nice progressbar to show script activity and bar charts +##----------------------------------------## +## Modified by Martinski W. [2024-Nov-02] ## +##----------------------------------------## +preparebar() +{ + # $1 - bar length + # $2 - bar char + barlen="$1" + barspaces="$(printf "%*s" "$1" ' ')" + barchars="$(printf "%*s" "$1" ' ' | tr ' ' "$2")" +} + +##----------------------------------------## +## Modified by Martinski W. [2024-Nov-02] ## +##----------------------------------------## +# Had to make some mods to the variables being passed, and created an inverse colored progress bar +progressbar() +{ + # $1 - number (-1 for clearing the bar) + # $2 - max number + # $3 - system name + # $4 - measurement + # $5 - standard/reverse progressbar + # $6 - alternate display values + # $7 - alternate value for progressbar exceeding 100% + + insertspc=" " + + if [ "$1" -eq -1 ] + then + printf "\r $barspaces\r" + else + if [ $# -gt 6 ] && [ -n "$7" ] && [ "$1" -ge "$7" ] + then + barch="$(($7*barlen/$2))" + barsp="$((barlen-barch))" + progr="$((100*$1/$2))" + else + barch="$(($1*barlen/$2))" + barsp="$((barlen-barch))" + progr="$((100*$1/$2))" + fi + + if [ $# -gt 5 ] && [ -n "$6" ]; then AltNum="$6" ; else AltNum="$1" ; fi + + if [ "$5" = "Standard" ] + then + if [ "$progr" -le 60 ]; then + printf "${InvGreen}${CWhite}$insertspc${CClear}${CWhite}${3} ${CDkGray}[${CGreen}%.${barch}s%.${barsp}s${CDkGray}]${CClear} ${CWhite}${InvDkGray}$AltNum ${4} / ${progr}%%\r${CClear}" "$barchars" "$barspaces" + elif [ "$progr" -gt 60 ] && [ "$progr" -le 85 ]; then + printf "${InvYellow}${CBlack}$insertspc${CClear}${CYellow}${3} ${CDkGray}[${CYellow}%.${barch}s%.${barsp}s${CDkGray}]${CClear} ${CWhite}${InvDkGray}$AltNum ${4} / ${progr}%%\r${CClear}" "$barchars" "$barspaces" + else + printf "${InvRed}${CWhite}$insertspc${CClear}${CRed}${3} ${CDkGray}[${CRed}%.${barch}s%.${barsp}s${CDkGray}]${CClear} ${CWhite}${InvDkGray}$AltNum ${4} / ${progr}%%\r${CClear}" "$barchars" "$barspaces" + fi + elif [ "$5" = "Reverse" ] + then + if [ "$progr" -le 15 ]; then + printf "${InvRed}${CWhite}$insertspc${CClear}${CRed}${3} ${CDkGray}[${CRed}%.${barch}s%.${barsp}s${CDkGray}]${CClear} ${CWhite}${InvDkGray}$AltNum ${4} / ${progr}%%\r${CClear}" "$barchars" "$barspaces" + elif [ "$progr" -gt 15 ] && [ "$progr" -le 40 ]; then + printf "${InvYellow}${CBlack}$insertspc${CClear}${CYellow}${3} ${CDkGray}[${CYellow}%.${barch}s%.${barsp}s${CDkGray}]${CClear} ${CWhite}${InvDkGray}$AltNum ${4} / ${progr}%%\r${CClear}" "$barchars" "$barspaces" + else + printf "${InvGreen}${CWhite}$insertspc${CClear}${CWhite}${3}${CGreen} ${CDkGray}[${CGreen}%.${barch}s%.${barsp}s${CDkGray}]${CClear} ${CWhite}${InvDkGray}$AltNum ${4} / ${progr}%%\r${CClear}" "$barchars" "$barspaces" + fi + elif [ "$5" = "CPU" ] + then + if [ "$progr" -le 80 ]; then + printf "${InvGreen}${CWhite}$insertspc${CClear}${CWhite}${3}${CGreen} ${CDkGray}[${CGreen}%.${barch}s%.${barsp}s${CDkGray}]${CClear} ${CWhite}${InvDkGray}$AltNum ${4} / ${progr}%%\r${CClear}" "$barchars" "$barspaces" + elif [ "$progr" -gt 80 ] && [ "$progr" -le 90 ]; then + printf "${InvYellow}${CBlack}$insertspc${CClear}${CYellow}${3} ${CDkGray}[${CYellow}%.${barch}s%.${barsp}s${CDkGray}]${CClear} ${CWhite}${InvDkGray}$AltNum ${4} / ${progr}%%\r${CClear}" "$barchars" "$barspaces" + else + printf "${InvRed}${CWhite}$insertspc${CClear}${CRed}${3} ${CDkGray}[${CRed}%.${barch}s%.${barsp}s${CDkGray}]${CClear} ${CWhite}${InvDkGray}$AltNum ${4} / ${progr}%%\r${CClear}" "$barchars" "$barspaces" + fi + fi + fi +} + +# ------------------------------------------------------------------------------------------------------------------------- +# Shows a more minimalistic progress bar that indicates seconds/% +##----------------------------------------## +## Modified by Martinski W. [2024-Nov-06] ## +##----------------------------------------## +progressbaroverride() +{ + # $1 - number (-1 for clearing the bar) + # $2 - max number + # $3 - system name + # $4 - measurement + # $5 - standard/reverse progressbar + # $6 - alternate display values + # $7 - alternate value for progressbar exceeding 100% + + local barch barsp percnt altNum readTimeSec + insertspc=" " + + _GetPercent_() { printf "%.1f" "$(echo "$1" | awk "{print $1}")" ; } + + _UpdateProgressBar_() + { + if [ "$2" = "Standard" ] && [ "$INITIALBOOT" -eq 0 ] + then + printf " ${CWhite}${InvDkGray}%3d${1} /%5.1f%%${CClear} [${CGreen}e${CClear}=Exit] [Selection? ${InvGreen} ${CClear}${CGreen}] ${pausedTimerDispStr} \r${CClear}" "$altNum" "$percnt" + elif [ "$2" = "Standard" ] && [ "$INITIALBOOT" -eq 1 ] + then + printf "${CDkGray} [${CGreen}%.${barch}s%.${barsp}s${CDkGray}] \r${CClear}" "$barchars" "$barspaces" + fi + } + + _PausedTimerHandler_() + { + local keyPress readTimeSec + while "$pausedTimerEnabled" + do + keyPress='' + readTimeSec="$(date +%s)" + read -rsn1 -t 1 keyPress < "$(tty 0>&2)" + if [ "$keyPress" = "X" ] + then + pausedTimerEnabled=false + pausedTimerDispStr="$(printf "%*s" "$pausedTimerMsgLen" ' ')" + break + fi + if [ "$(date +%s)" -lt "$((readTimeSec + 1))" ] + then + stty -icanon min 0 time 5 + cat - > /dev/null + fi + done + } + + if [ "$1" -eq -1 ] + then + printf "\r $barspaces\r" + else + if [ $# -gt 6 ] && [ -n "$7" ] && [ "$1" -ge "$7" ] + then + barch="$(($7*barlen/$2))" + barsp="$((barlen-barch))" + percnt="$(_GetPercent_ "(100*$1/$2)")" + else + barch="$(($1*barlen/$2))" + barsp="$((barlen-barch))" + percnt="$(_GetPercent_ "(100*$1/$2)")" + fi + + if [ $# -gt 5 ] && [ -n "$6" ]; then altNum="$6" ; else altNum="$1" ; fi + + _UpdateProgressBar_ "$4" "$5" + + if [ "$INITIALBOOT" = "0" ] + then + # Borrowed this wonderful keypress capturing mechanism from @Eibgrad... thank you! :) + readTimeSec="$(date +%s)" + key_press=''; read -rsn1 -t 1 key_press < "$(tty 0>&2)" + + if [ "$key_press" ] + then + case "$key_press" in + [Cc]) QueueNetworkConn=1 + echo -e "${CClear}[Queuing Network Connection Stats] "; + sleep 1; NextPage=6; timerReset=1 + ;; + [Dd]) QueueNetworkDiag=1 + echo -e "${CClear}[Queuing Network Diagnostics] "; + sleep 1; NextPage=5; timerReset=1 + ;; + [Ee]) clear; logoNMexit; echo -e "${CClear}"; exit 0 + ;; + [Gg]) NCView="WG"; NextPage=6; timerReset=1 + ;; + [Hh]) hideoptions=1 ; [ "$hideoptions" != "$prevHideOpts" ] && timerReset=1 + ;; + [Ii]) QueueSpdTest=1 + echo -e "${CClear}[Queuing WAN Speedtest] "; + sleep 1; NextPage=4; timerReset=1 + ;; + [Ll]) NCView="LAN"; NextPage=6; timerReset=1 + ;; + [Mm]) _IgnoreKeypresses_ OFF + FromUI=1; vsetup; source "$CFGPATH" + echo -e "\n${CClear}[Returning to the Main UI momentarily] "; + sleep 1; FromUI=0; timerReset=1 + ;; + [Nn]) timerReset=1 + if [ "$NextPage" = "1" ]; then NextPage=2 + elif [ "$NextPage" = "2" ]; then NextPage=3 + elif [ "$NextPage" = "3" ]; then NextPage=4 + elif [ "$NextPage" = "4" ]; then NextPage=5 + elif [ "$NextPage" = "5" ]; then NextPage=6 + elif [ "$NextPage" = "6" ]; then NextPage=7 + elif [ "$NextPage" = "7" ]; then NextPage=1 + fi + ;; + [Oo]) _IgnoreKeypresses_ OFF ; vlogs ;; + [Pp]) timerReset=1 + if [ "$NextPage" = "1" ]; then NextPage=7 + elif [ "$NextPage" = "2" ]; then NextPage=1 + elif [ "$NextPage" = "3" ]; then NextPage=2 + elif [ "$NextPage" = "4" ]; then NextPage=3 + elif [ "$NextPage" = "5" ]; then NextPage=4 + elif [ "$NextPage" = "6" ]; then NextPage=5 + elif [ "$NextPage" = "7" ]; then NextPage=6 + fi + ;; + [Rr]) if [ "$autorotate" = 0 ] + then autorotate=1; autorotateindicator="ON" + elif [ "$autorotate" = "1" ] + then autorotate=0; autorotateindicator="OFF" + fi + timerReset=1 + ;; + [Ss]) hideoptions=0 ; [ "$hideoptions" != "$prevHideOpts" ] && timerReset=1 + ;; + [Tt]) PSView="TCP"; NextPage=5; timerReset=1 + ;; + [Uu]) PSView="UDP"; NextPage=5; timerReset=1 + ;; + [Vv]) NCView="VPN"; NextPage=6; timerReset=1 + ;; + [Ww]) NCView="WAN"; NextPage=6; timerReset=1 + ;; + X) if "$pausedTimerEnabled" + then + pausedTimerEnabled=false + pausedTimerDispStr="$(printf "%*s" "$pausedTimerMsgLen" ' ')" + else + pausedTimerEnabled=true + pausedTimerDispStr="${CWhite}${InvRed}${pausedTimerMsgStr}${CClear}" + _UpdateProgressBar_ "$4" "$5" + _PausedTimerHandler_ + fi + ;; + 1) QueueVPNSlot1=1 + echo -e "${CClear}[Queuing VPN1 Speedtest] "; + sleep 1; NextPage=4; timerReset=1 + ;; + 2) QueueVPNSlot2=1 + echo -e "${CClear}[Queuing VPN2 Speedtest] "; + sleep 1; NextPage=4; timerReset=1 + ;; + 3) QueueVPNSlot3=1 + echo -e "${CClear}[Queuing VPN3 Speedtest] "; + sleep 1; NextPage=4; timerReset=1 + ;; + 4) QueueVPNSlot4=1 + echo -e "${CClear}[Queuing VPN4 Speedtest] "; + sleep 1; NextPage=4; timerReset=1 + ;; + 5) QueueVPNSlot5=1 + echo -e "${CClear}[Queuing VPN5 Speedtest] "; + sleep 1; NextPage=4; timerReset=1 + ;; + 6) QueueWGSlot1=1 + echo -e "${CClear}[Queuing WG1 Speedtest] "; + sleep 1; NextPage=4; timerReset=1 + ;; + 7) QueueWGSlot2=1 + echo -e "${CClear}[Queuing WG2 Speedtest] "; + sleep 1; NextPage=4; timerReset=1 + ;; + 8) QueueWGSlot3=1 + echo -e "${CClear}[Queuing WG3 Speedtest] "; + sleep 1; NextPage=4; timerReset=1 + ;; + 9) QueueWGSlot4=1 + echo -e "${CClear}[Queuing WG4 Speedtest] "; + sleep 1; NextPage=4; timerReset=1 + ;; + 0) QueueWGSlot5=1 + echo -e "${CClear}[Queuing WG5 Speedtest] "; + sleep 1; NextPage=4; timerReset=1 + ;; + + [\!]) SortbyOpt="Name"; [ "$SortbyOpt" != "$prevSortByOpt" ] && [ "$NextPage" = "7" ] && timerReset=1 ;; + [\@]) SortbyOpt="IP"; [ "$SortbyOpt" != "$prevSortByOpt" ] && [ "$NextPage" = "7" ] && timerReset=1 ;; + [\#]) SortbyOpt="MAC"; [ "$SortbyOpt" != "$prevSortByOpt" ] && [ "$NextPage" = "7" ] && timerReset=1 ;; + *) ;; ##IGNORE INVALID key presses ## + esac + _IgnoreKeypresses_ ON + if [ "$(date +%s)" -lt "$((readTimeSec + 1))" ] + then + stty -icanon min 0 time 1 + cat - > /dev/null + fi + fi + else + ## Initial Boot Sequence Loop ## + _ConsumeKeypressBuffer_ + fi + fi +} + +# ------------------------------------------------------------------------------------------------------------------------- +# converttemps converts temp readouts from C to F or K + +converttemps () { +# $1 is the incoming C Temp + + if [ "$TempUnits" == "F" ]; then + currenttemp=$(awk -v v1=$1 'BEGIN{printf "%0.2f\n", (v1*9)/5+32}' | cut -d . -f 1) + currentrange=212 + elif [ "$TempUnits" == "K" ]; then + currenttemp=$(awk -v v1=$1 'BEGIN{printf "%0.2f\n", v1+273}' | cut -d . -f 1) + currentrange=373 + elif [ "$TempUnits" == "C" ]; then + currenttemp=$1 + currentrange=100 + else + # Default to C if someone entered something other than C, F or K + TempUnits="C" + currenttemp=$1 + currentrange=100 + fi + +} + +# ------------------------------------------------------------------------------------------------------------------------- +# updatecheck downloads the latest update version file from github, and compares it with what's currently installed + +updatecheck () { + + # Download the latest version file from the source repository + curl --silent --retry 3 "https://raw.githubusercontent.com/ViktorJp/RTRMON/master/version.txt" -o "/jffs/addons/rtrmon.d/version.txt" + + if [ -f $DLVERPATH ] + then + # Read in its contents for the current version file + DLVersion=$(cat $DLVERPATH) + + # Compare the new version with the old version and log it + if [ "$Beta" == "1" ]; then # Check if Dev/Beta Mode is enabled and disable notification message + UpdateNotify=0 + elif [ "$DLVersion" != "$Version" ]; then + DLVersionPF=$(printf "%-8s" $DLVersion) + VersionPF=$(printf "%-8s" $Version) + UpdateNotify="${InvYellow} ${InvDkGray}${CWhite} Update available: v$VersionPF -> v$DLVersionPF ${CClear}" + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new update (v$DLVersion) is available to download" >> $LOGFILE + else + UpdateNotify=0 + fi + fi +} + +# ------------------------------------------------------------------------------------------------------------------------- +# calls the nano text editor to view the RTRMON log file + +vlogs() { + +export TERM=linux +nano +999999 --linenumbers $LOGFILE +timerReset=1 + +} + +# ------------------------------------------------------------------------------------------------------------------------- +# trimlogs will cut down log size (in rows) based on custom value + +trimlogs() +{ + + if [ "$LOGSIZE" -gt 0 ] + then + currlogsize=$(wc -l $LOGFILE | awk '{ print $1 }' ) # Determine the number of rows in the log + + if [ "$currlogsize" -gt "$LOGSIZE" ] # If it's bigger than the max allowed, tail/trim it! + then + echo "$(tail -$LOGSIZE $LOGFILE)" > $LOGFILE + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: Trimmed the log file down to $LOGSIZE lines" >> $LOGFILE + fi + + fi +} + +# ------------------------------------------------------------------------------------------------------------------------- +# vconfig guides you through the various configuration options for RTRMON +##----------------------------------------## +## Modified by Martinski W. [2024-Nov-02] ## +##----------------------------------------## +vconfig() +{ + _SetUpTimeoutCmdVars_ + + if [ -f "$CFGPATH" ] #Making sure file exists before proceeding + then + source "$CFGPATH" + + CHANGES=0 #track notification to save your changes# + + while true + do + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} RTRMON Configuration Options ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please choose from the various options below, which allow you to modify certain${CClear}" + echo -e "${InvGreen} ${CClear} customizable parameters that affect the operation of this script.${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 1)${CClear} : Timer Interval (seconds) : ${CGreen}$Interval" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 2)${CClear} : Max Internet Download Speed (Mbps) : ${CGreen}$MaxSpeedInet" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 3)${CClear} : Max Internet Upload Speed (Mbps) : ${CGreen}$MaxSpeedInetUL" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 4)${CClear} : Max LAN Speed (Mbps) : ${CGreen}$MaxSpeedLAN" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 5)${CClear} : Max 2.4GHz Speed (Mbps) : ${CGreen}$MaxSpeed24Ghz" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 6)${CClear} : Max 5GHz Speed (Mbps) : ${CGreen}$MaxSpeed5Ghz" + + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 7)${CClear} : Max 6GHz Speed (Mbps) : ${CGreen}$MaxSpeed6Ghz" + else + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 7)${CClear} : ${CDkGray}Max 6GHz Speed (Mbps) : N/A" + fi + + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 8)${CClear} : Temperature Units (C/F/K) : ${CGreen}$TempUnits" + + echo -en "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 9)${CClear} : Enable Ookla Speedtest? (Y/N) : ${CGreen}" + if [ "$Speedtst" = "0" ] + then printf "No\n" + else printf "Yes\n" + fi + + if [ "$spdtestsvrID" == "0" ] && [ "$Speedtst" == "1" ]; then + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(10)${CClear} : Custom Speedtest Server ID? : ${CGreen}Use Closest" + elif [ "$spdtestsvrID" != "0" ] && [ "$Speedtst" == "1" ]; then + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(10)${CClear} : Custom Speedtest Server ID? : ${CGreen}$spdtestsvrID" + else + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(10)${CClear} : Custom Speedtest Server ID? : ${CDkGray}N/A" + fi + + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(11)${CClear} : WAN0 Interface Override? : ${CGreen}$WANOverride" + + if [ "$WAN0AltModes" == "0" ]; then WAN0AltModesdisp="No"; else WAN0AltModesdisp="Yes"; fi + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(12)${CClear} : Mark Router As iMesh Node/Repeater/Bridge? : ${CGreen}$WAN0AltModesdisp" + if [ "$VPNSite2Site" == "0" ]; then VPNSite2Sitedisp="No"; else VPNSite2Sitedisp="Yes"; fi + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(13)${CClear} : Mark Router As VPN Site-To-Site Only? : ${CGreen}$VPNSite2Sitedisp" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(14)${CClear} : Custom Event Log Size? : ${CGreen}$LOGSIZE" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite} | ${CClear}" + + if [ $CHANGES -eq 0 ]; then + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( s)${CClear} : Save Config & Exit" + else + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( s)${CClear} : Save Config & Exit ${CWhite}${InvRed}<-- Save your changes! ${CClear}" + fi + + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( e)${CClear} : Exit & Discard Changes" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + read -p "Please select? (1-14, s=Save, e=Exit): " ConfigSelection + CHANGES=1 + # Execute chosen selections + case "$ConfigSelection" in + + 1) # ----------------------------------------------------------------------------------------- + while true + do + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Refresh Interval ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please indicate after how many seconds you would like RTRMON to refresh your stats?${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} (Default = 10 seconds)${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo + echo -e "${CClear}Current Refresh Interval: ${CGreen}${Interval}${CClear} seconds" + echo + read -p "Please enter value in seconds [5-999] (e=Exit): " newInterval + if [ -z "$newInterval" ] || echo "$newInterval" | grep -qE "^(e|E)$" + then + if echo "$Interval" | grep -qE "^([1-9][0-9]{0,2})$" && \ + [ "$Interval" -ge 5 ] && [ "$Interval" -le 999 ] + then + timer="$Interval" + printf "\n${CClear}[Exiting]\n" + sleep 1 ; break + else + printf "\n${CRed}*ERROR*: Please enter a valid number between 5 and 999.${CClear}\n" + _PressAnyKeyToContinue_ + fi + elif echo "$newInterval" | grep -qE "^([1-9][0-9]{0,2})$" && \ + [ "$newInterval" -ge 5 ] && [ "$newInterval" -le 999 ] + then + Interval="$newInterval" + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new refresh interval ($Interval) has been selected." >> $LOGFILE + CHANGES=1 + timer="$Interval" + printf "\n${CClear}[OK]\n" + sleep 1 ; break + else + printf "\n${CRed}*ERROR*: Please enter a valid number between 5 and 999.${CClear}\n" + _PressAnyKeyToContinue_ + fi + done + ;; + + 2) # ----------------------------------------------------------------------------------------- + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Maximum Internet Download Bandwidth ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please indicate what your maximum internet download bandwidth/speed is in Mbps?${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} (Default = 50 Mbps)${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${CClear}Current: ${CGreen}$MaxSpeedInet${CClear} Mbps" + echo "" + read -p 'Please enter value in Mbps (ex: 1000): ' MaxSpeedInet1 + MaxSpeedInet2=$(echo $MaxSpeedInet1 | tr -d -c 0-9) + if [ -z "$MaxSpeedInet1" ]; then MaxSpeedInet=50; else MaxSpeedInet=$MaxSpeedInet2; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new Internet Download Bandwidth soeed ($MaxSpeedInet Mbps) has been selected." >> $LOGFILE + ;; + + 3) # ----------------------------------------------------------------------------------------- + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Maximum Internet Upload Bandwidth ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please indicate what your maximum internet upload bandwidth/speed is in Mbps?${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} (Default = 50 Mbps)${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${CClear}Current: ${CGreen}$MaxSpeedInetUL${CClear} Mbps" + echo "" + read -p 'Please enter value in Mbps (ex: 1000): ' MaxSpeedInetUL1 + MaxSpeedInetUL2=$(echo $MaxSpeedInetUL1 | tr -d -c 0-9) + if [ -z "$MaxSpeedInetUL1" ]; then MaxSpeedInetUL=50; else MaxSpeedInetUL=$MaxSpeedInetUL2; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new Internet Upload Bandwidth speed ($MaxSpeedInetUL Mbps) has been selected." >> $LOGFILE + ;; + + 4) # ----------------------------------------------------------------------------------------- + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Maximum Local Area Network (LAN) Bandwidth ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please indicate what your maximum LAN bandwidth/speed is in Mbps?${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} (Default = 1000 Mbps)${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${CClear}Current: ${CGreen}$MaxSpeedLAN${CClear} Mbps" + echo "" + read -p 'Please enter value in Mbps (ex: 1000): ' MaxSpeedLAN1 + MaxSpeedLAN2=$(echo $MaxSpeedLAN1 | tr -d -c 0-9) + if [ -z "$MaxSpeedLAN1" ]; then MaxSpeedLAN=1000; else MaxSpeedLAN=$MaxSpeedLAN2; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new LAN Bandwidth speed ($MaxSpeedLAN Mbps) has been selected." >> $LOGFILE + ;; + + 5) # ----------------------------------------------------------------------------------------- + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Maximum 2.4GHz Bandwidth Speed ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please indicate what your maximum realistic 2.4GHz speed is in Mbps?${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} (Default = 450 Mbps)${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${CClear}Current: ${CGreen}$MaxSpeed24Ghz${CClear} Mbps" + echo "" + read -p 'Please enter value in Mbps (ex: 1000): ' MaxSpeed24Ghz1 + MaxSpeed24Ghz2=$(echo $MaxSpeed24Ghz1 | tr -d -c 0-9) + if [ -z "$MaxSpeed24Ghz1" ]; then MaxSpeed24Ghz=450; else MaxSpeed24Ghz=$MaxSpeed24Ghz2; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new 2.4GHz Bandwidth speed ($MaxSpeed24Ghz Mbps) has been selected." >> $LOGFILE + ;; + + 6) # ----------------------------------------------------------------------------------------- + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Maximum 5GHz Bandwidth Speed ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please indicate what your maximum realistic 5GHz speed is in Mbps?${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} (Default = 780 Mbps)${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${CClear}Current: ${CGreen}$MaxSpeed5Ghz${CClear} Mbps" + echo "" + read -p 'Please enter value in Mbps (ex: 1000): ' MaxSpeed5Ghz1 + MaxSpeed5Ghz2=$(echo $MaxSpeed5Ghz1 | tr -d -c 0-9) + if [ -z "$MaxSpeed5Ghz1" ]; then MaxSpeed5Ghz=780; else MaxSpeed5Ghz=$MaxSpeed5Ghz2; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new 5GHz Bandwidth speed ($MaxSpeed5Ghz Mbps) has been selected." >> $LOGFILE + ;; + + 7) # ----------------------------------------------------------------------------------------- + clear + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then + echo -e "${InvGreen} ${InvDkGray}${CWhite} Maximum 6GHz Bandwidth Speed ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please indicate what your maximum realistic 6GHz speed is in Mbps?${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} (Default = 920 Mbps)${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${CClear}Current: ${CGreen}$MaxSpeed6Ghz${CClear} Mbps" + echo "" + read -p 'Please enter value in Mbps (ex: 1000): ' MaxSpeed6Ghz1 + MaxSpeed6Ghz2=$(echo $MaxSpeed6Ghz1 | tr -d -c 0-9) + if [ -z "$MaxSpeed6Ghz1" ]; then MaxSpeed6Ghz=920; else MaxSpeed6Ghz=$MaxSpeed6Ghz2; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new 6GHz Bandwidth speed ($MaxSpeed6Ghz Mbps) has been selected." >> $LOGFILE + else + echo -e "${CRed}This item is currently only available for router models:" + echo -e "GT-AXE11000, GT-AXE16000, RT-BE96U, RT-BE92U and GT-BE98_Pro" + echo "" + sleep 3 + fi + ;; + + 8) # ----------------------------------------------------------------------------------------- + while true + do + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Temperature Unit Preferences ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please indicate what Temperature Units you would prefer to use?${CClear}" + echo -e "${InvGreen} ${CClear} (C)elcius, (F)ahrenheit or (K)elvin" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} (Default = C)${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${CClear}Current: ${CGreen}$TempUnits${CClear}" + echo "" + read -p 'Temp Units (C/F/K): ' TempUnits1 + case "$TempUnits1" in + [Cc]) TempUnits="C" ; break ;; + [Ff]) TempUnits="F" ; break ;; + [Kk]) TempUnits="K" ; break ;; + *) + printf "\n*ERROR*: Please enter a valid option.${CClear}\n" + sleep 2 + ;; + esac + done + if [ -z "$TempUnits1" ]; then TempUnits="C"; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new Temperature Unit ($TempUnits) has been selected." >> $LOGFILE + ;; + + 9) # ----------------------------------------------------------------------------------------- + echo "" + if [ -f $OOKLAPATH ]; then + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Remove Ookla Speedtest Binaries ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Would you like to disable and uninstall the Ookla Speedtest binaries from RTRMON?${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${CClear}Current: ${CGreen}Ookla Speedtest Installed${CClear}" + echo "" + echo -e "Remove Speedtest binaries from RTRMON?${CClear}" + if promptyn "[y/n]: " + then + echo "" + echo "" + echo -e "${CClear}Removing Ookla Speedtest binaries..." + rm "/jffs/addons/rtrmon.d/speedtest" + rm "/jffs/addons/rtrmon.d/speedtest.5" + rm "/jffs/addons/rtrmon.d/speedtest.md" + sleep 1 + if [ ! -f $OOKLAPATH ]; then + echo "" + echo -e "${CClear}Completed removing Ookla Speedtest binaries..." + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: Ookla Speedtest binaries have been successfully removed." >> $LOGFILE + Speedtst=0 + spdtestsvrID=0 + echo "" + read -rsp $'Press any key to continue...\n' -n1 key + else + echo "" + echo -e "${CRed}ERROR: Ookla Speedtest binaries were unable to be removed...${CClear}" + echo -e "Please manually resolve issue under /jffs/addons/rtrmon.d folder" + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - ERROR: Ookla Speedtest binaries were unable to be successfully removed." >> $LOGFILE + Speedtst=1 + echo "" + read -rsp $'Press any key to continue...\n' -n1 key + fi + else + echo "" + echo "" + echo -e "${CClear}Canceling removing Ookla Speedtest binaries..." + sleep 2 + fi + + else + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Install Ookla Speedtest Binaries ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Would you like to install and enable the Ookla Speedtest binaries for use with${CClear}" + echo -e "${InvGreen} ${CClear} RTRMON? Please read the following before accepting agreement:${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} You may only use this Speedtest software and information generated from it for${CClear}" + echo -e "${InvGreen} ${CClear} personal, non-commercial use, through a command line interface on a personal${CClear}" + echo -e "${InvGreen} ${CClear} computer. Your use of this software is subject to the End User License${CClear}" + echo -e "${InvGreen} ${CClear} Agreement, Terms of Use and Privacy Policy at these URLs:${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} https://www.speedtest.net/about/eula${CClear}" + echo -e "${InvGreen} ${CClear} https://www.speedtest.net/about/terms${CClear}" + echo -e "${InvGreen} ${CClear} https://www.speedtest.net/about/privacy${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${CClear}Current: ${CGreen}Ookla Speedtest Not Installed${CClear}" + echo "" + echo -e "By typing 'y' below, you agree to these terms.${CClear}" + if promptyn "[y/n]: "; then + echo "" + echo "" + echo -e "Installing Ookla Speedtest binaries..." + echo "" + if [ "$(uname -m)" = "aarch64" ]; then + curl --silent --retry 3 "https://install.speedtest.net/app/cli/ookla-speedtest-1.2.0-linux-aarch64.tgz" -o "/jffs/addons/rtrmon.d/spdtst64.tgz" + tar -zxf /jffs/addons/rtrmon.d/spdtst64.tgz -C /jffs/addons/rtrmon.d 2>/dev/null + chmod 0755 "/jffs/addons/rtrmon.d/speedtest" + rm /jffs/addons/rtrmon.d/spdtst64.tgz + else + curl --silent --retry 3 "https://install.speedtest.net/app/cli/ookla-speedtest-1.2.0-linux-armel.tgz" -o "/jffs/addons/rtrmon.d/spdtstel.tgz" + tar -zxf /jffs/addons/rtrmon.d/spdtstel.tgz -C /jffs/addons/rtrmon.d 2>/dev/null + chmod 0755 "/jffs/addons/rtrmon.d/speedtest" + rm /jffs/addons/rtrmon.d/spdtstel.tgz + fi + if [ -f /jffs/addons/rtrmon.d/speedtest ]; then + echo -e "${CClear}Ookla Speedtest binaries installed successfully..." + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: Ookla Speedtest binaries were successfully installed." >> $LOGFILE + Speedtst=1 + echo "" + read -rsp $'Press any key to initialize Speedtest and accept license...\n' -n1 key + /jffs/addons/rtrmon.d/speedtest + cp /root/.config/ookla/speedtest-cli.json /jffs/addons/rtrmon.d/speedtest-cli.json 2>/dev/null + echo "" + read -rsp $'Press any key to continue...\n' -n1 key + else + echo -e "${CRed}ERROR: Ookla Speedtest binaries install failed...${CClear}" + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - ERROR: Ookla Speedtest binaries were unable to be successfully installed." >> $LOGFILE + Speedtst=0 + spdtestsvrID=0 + echo "" + read -rsp $'Press any key to continue...\n' -n1 key + fi + else + echo "" + echo "" + echo -e "${CClear}Canceling install of Ookla Speedtest binaries..." + Speedtst=0 + spdtestsvrID=0 + sleep 2 + fi + fi + ;; + + 10) # ----------------------------------------------------------------------------------------- + if [ "$Speedtst" == "0" ]; then return; fi + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Custom Speedtest Server ID ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please indicate if you would like to use a custom Speedtest Server ID? These IDs${CClear}" + echo -e "${InvGreen} ${CClear} can be found by running a Speedtest on your browser and noting the ID of the server${CClear}" + echo -e "${InvGreen} ${CClear} in its URL when hovering your mouse over it. Enter an ID number, or use 0 to choose${CClear}" + echo -e "${InvGreen} ${CClear} the closest server to you.${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} (Default = 0)${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${CClear}Current: ${CGreen}$spdtestsvrID${CClear}" + echo "" + read -p 'Speedtest Server ID: ' spdtestsvrID1 + spdtestsvrID2=$(echo $spdtestsvrID1 | tr -d -c 0-9) + if [ -z "$spdtestsvrID1" ]; then spdtestsvrID=0; else spdtestsvrID=$spdtestsvrID2; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: Ookla Speedtest custom server ID ($spdtestsvrID) was configured." >> $LOGFILE + ;; + + 11) # ----------------------------------------------------------------------------------------- + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Override WAN0 Interface ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please indicate if you would like to override the default interface assigned to${CClear}" + echo -e "${InvGreen} ${CClear} your local WAN0? Typically, 'eth0' is assigned to WAN0, but based on how you've${CClear}" + echo -e "${InvGreen} ${CClear} rigged your router, it might be something else. By default, RTRMON will${CClear}" + echo -e "${InvGreen} ${CClear} automatically try to determine the correct interface, however this will give${CClear}" + echo -e "${InvGreen} ${CClear} you the option to override it should you be using something else.${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} (Default = 0)${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${CClear}Current: ${CGreen}$WANOverride${CClear}" + echo "" + echo -e "${CGreen}Valid interface choices:" + + ip -br link | LC_ALL=C awk '$2 == "UP" {print $1}' > $IFLIST # Extract all valid interfaces to a text file + + LINES=$(cat $IFLIST | wc -l) #Check to see how many lines are in this file + + echo -e "${CClear}0) Auto" + + i=0 # Populate all other numbered choices + while [ $i -ne $LINES ] + do + i=$(($i+1)) + InterfaceName=$(sed -n "${i}p" $IFLIST) + echo -e "$i) $InterfaceName" + done + + echo -e "${CClear}" + echo -e "(Default = 0 (Auto), or choose one of the above)${CClear}" + + while true + do + read -p 'Choose Interface #: ' ChooseInterface + + case ${ChooseInterface#[-+]} in # Make sure we're only picking an item from the list + *[!0-9]* | '') echo ""; echo -e "\n${CRed}ERROR: Please make a valid selection${CClear}"; echo "" ;; + * ) if [ $ChooseInterface -lt 0 ] || [ $ChooseInterface -gt $LINES ]; then echo ""; echo -e "\n${CRed}Please make a valid selection${CClear}"; echo ""; else break; fi ;; + esac + + done + + if [ -z "$ChooseInterface" ] # Assign the interface name to a variable and save it + then + WANOverride="Auto" + elif [ $ChooseInterface -eq 0 ] + then + WANOverride="Auto" + else + WANOverride=$(sed -n "${ChooseInterface}p" $IFLIST) + fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: WAN0 Override ($WANOverride) was configured." >> $LOGFILE + ;; + + 12) # ----------------------------------------------------------------------------------------- + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Mark Router As iMesh Node/Repeater/Bridge ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please indicate if you would like to mark that this router is being used as an${CClear}" + echo -e "${InvGreen} ${CClear} iMesh Node, Repeater or Bridge operating mode. In cases like this, the WAN0${CClear}" + echo -e "${InvGreen} ${CClear} interface will be non-functional, and will be omitted from being captured by${CClear}" + echo -e "${InvGreen} ${CClear} RTRMON's stats.${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} (Default = No)${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + if [ "$WAN0AltModes" == "0" ]; then WAN0AltModesdisp="No"; else WAN0AltModesdisp="Yes"; fi + echo -e "${CClear}Current: ${CGreen}$WAN0AltModesdisp${CClear}" + echo "" + echo -e "Is this router an iMesh Node/Repeater/Bridge?${CClear}" + if promptyn "[y/n]: "; then + WAN0AltModes=1 + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: This device's operating mode was marked as an iMesh Node/AP/Repeater/Bridge." >> $LOGFILE + else + WAN0AltModes=0 + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: This device's operating mode was marked as a Router." >> $LOGFILE + fi + ;; + + 13) # ----------------------------------------------------------------------------------------- + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Mark VPN As Site-To-Site Only ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please indicate if you would like to mark that this router is purely being used${CClear}" + echo -e "${InvGreen} ${CClear} in a VPN Site-To-Site only configuration. In cases like this, the public-facing${CClear}" + echo -e "${InvGreen} ${CClear} IP is a private IP, which could hinder certain network connection and bandwidth$CClear}" + echo -e "${InvGreen} ${CClear} tests, and potentially cause delays and/or a lack of data.${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} By default, it is assumed that this router's VPN configuration will be marked${CClear}" + echo -e "${InvGreen} ${CClear} as being in a normal VPN provider configuration.${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} (Default = No)${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + if [ "$VPNSite2Site" == "0" ]; then VPNSite2Sitedisp="No"; else VPNSite2Sitedisp="Yes"; fi + echo -e "${CClear}Current: ${CGreen}$VPNSite2Sitedisp${CClear}" + echo "" + echo -e "Is this router purely used in a VPN Site-to-Site Configuration?${CClear}" + if promptyn "[y/n]: "; then + VPNSite2Site=1 + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: This device's VPN operating mode was marked as being in a VPN Site-to-Site only configuration." >> $LOGFILE + else + VPNSite2Site=0 + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: This device's VPN operating mode was marked as being in a Normal VPN Provider configuration." >> $LOGFILE + fi + ;; + + 14) + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Custom Event Log Size ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please indicate below how large you would like your Event Log to grow. I'm a poet${CClear}" + echo -e "${InvGreen} ${CClear} and didn't even know it. By default, with 2000 rows, you will have many months of${CClear}" + echo -e "${InvGreen} ${CClear} Event Log data." + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Use 0 to Disable, max number of rows is 9999. (Default = 2000)" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${CClear}Current: ${CGreen}$LOGSIZE${CClear}" + echo "" + read -p "Please enter Log Size (in rows)? (0-9999, e=Exit): " NEWLOGSIZE + if [ -z "$NEWLOGSIZE" ] || [ "$NEWLOGSIZE" = "e" ] + then + printf "\n[Exiting]\n"; sleep 2 + elif [ $NEWLOGSIZE -ge 0 ] && [ $NEWLOGSIZE -le 9999 ] + then + LOGSIZE="$NEWLOGSIZE" + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: New custom Event Log Size entered (in rows): $LOGSIZE" >> $LOGFILE + else + LOGSIZE=2000 + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: New custom Event Log Size entered (in rows): $LOGSIZE" >> $LOGFILE + fi + ;; + + [Ss]) # ----------------------------------------------------------------------------------------- + echo "" + { echo 'Interval='$Interval + echo 'MaxSpeedInet='$MaxSpeedInet + echo 'MaxSpeedInetUL='$MaxSpeedInetUL + echo 'MaxSpeedLAN='$MaxSpeedLAN + echo 'MaxSpeed24Ghz='$MaxSpeed24Ghz + echo 'MaxSpeed5Ghz='$MaxSpeed5Ghz + echo 'MaxSpeed6Ghz='$MaxSpeed6Ghz + echo 'TempUnits="'"$TempUnits"'"' + echo 'Speedtst='$Speedtst + echo 'spdtestsvrID='$spdtestsvrID + echo 'WANOverride="'"$WANOverride"'"' + echo 'WAN0AltModes='$WAN0AltModes + echo 'VPNSite2Site='$VPNSite2Site + echo 'LOGSIZE='$LOGSIZE + } > $CFGPATH + echo -e "\n${CClear}Applying config changes to RTRMON..." + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: New Config file was successfully written." >> $LOGFILE + sleep 3 + return + ;; + + [Ee]) # ----------------------------------------------------------------------------------------- + return + ;; + + esac + done + + else + #Create a new config file with default values to get it to a basic running state + { echo 'Interval=10' + echo 'MaxSpeedInet=1000' + echo 'MaxSpeedInetUL=50' + echo 'MaxSpeedLAN=1000' + echo 'MaxSpeed24Ghz=450' + echo 'MaxSpeed5Ghz=780' + echo 'MaxSpeed6Ghz=920' + echo 'TempUnits="C"' + echo 'Speedtst=0' + echo 'spdtestsvrID=0' + echo 'WANOverride="Auto"' + echo 'WAN0AltModes=0' + echo 'VPNSite2Site=0' + echo 'LOGSIZE=2000' + } > $CFGPATH + + #Re-run rtrmon -config to restart setup process + vconfig + + fi + +} + +# ------------------------------------------------------------------------------------------------------------------------- + +# vuninstall is a function that uninstalls and removes all traces of RTRMON from your router... +vuninstall () { + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Uninstall Utility ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} You are about to uninstall RTRMON! This action is irreversible." + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "Do you wish to proceed?${CClear}" + if promptyn "[y/n]: "; then + echo "" + echo -e "\nAre you sure? Please type 'Y' to validate you want to proceed.${CClear}" + if promptyn "[y/n]: "; then + clear + rm -r /jffs/addons/rtrmon.d + rm /jffs/scripts/rtrmon.sh + echo "" + echo -e "\nRTRMON has been uninstalled...${CClear}" + echo "" + exit 0 + else + echo "" + echo -e "\nExiting Uninstall Utility...${CClear}" + sleep 1 + return + fi + else + echo "" + echo -e "\nExiting Uninstall Utility...${CClear}" + sleep 1 + return + fi +} + + +# ------------------------------------------------------------------------------------------------------------------------- + +# vupdate is a function that provides a UI to check for script updates and allows you to install the latest version... +vupdate () { + updatecheck # Check for the latest version from source repository + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Update Utility ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} This utility allows you to check, download and install updates" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "Current Version: ${CGreen}$Version${CClear}" + echo -e "Updated Version: ${CGreen}$DLVersion${CClear}" + echo "" + if [ "$Version" == "$DLVersion" ] + then + echo -e "You are on the latest version! Would you like to download anyways?${CClear}" + echo -e "This will overwrite your local copy with the current build.${CClear}" + if promptyn "[y/n]: "; then + echo "" + echo "" + echo -e "Downloading RTRMON ${CGreen}v$DLVersion${CClear}" + curl --silent --retry 3 "https://raw.githubusercontent.com/ViktorJp/RTRMON/master/rtrmon.sh" -o "/jffs/scripts/rtrmon.sh" && chmod 755 "/jffs/scripts/rtrmon.sh" + echo "" + echo -e "Download successful!${CClear}" + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: Successfully downloaded RTRMON v$DLVersion." >> $LOGFILE + echo "" + read -rsp $'Press any key to continue...\n' -n1 key + exec sh /jffs/scripts/rtrmon.sh -monitor + else + echo "" + echo "" + echo -e "Exiting Update Utility...${CClear}" + sleep 1 + return + fi + else + echo -e "Score! There is a new version out there! Would you like to update?${CClear}" + if promptyn "[y/n]: "; then + echo "" + echo "" + echo -e "Downloading RTRMON ${CYellow}v$DLVersion${CClear}" + curl --silent --retry 3 "https://raw.githubusercontent.com/ViktorJp/RTRMON/master/rtrmon.sh" -o "/jffs/scripts/rtrmon.sh" && chmod 755 "/jffs/scripts/rtrmon.sh" + echo "" + echo -e "Download successful!${CClear}" + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: Successfully downloaded RTRMON v$DLVersion." >> $LOGFILE + echo "" + read -rsp $'Press any key to continue...\n' -n1 key + exec sh /jffs/scripts/rtrmon.sh -monitor + else + echo "" + echo "" + echo -e "Exiting Update Utility...${CClear}" + sleep 1 + return + fi + fi +} + +# ------------------------------------------------------------------------------------------------------------------------- +##----------------------------------------## +## Modified by Martinski W. [2024-Nov-02] ## +##----------------------------------------## +# Function that sets up, configures and allows you to launch RTRMON on your router... +vsetup() +{ + _SetUpTimeoutCmdVars_ + + # Check for and add an alias for RTRMON # + if ! grep -F "sh /jffs/scripts/rtrmon.sh" /jffs/configs/profile.add >/dev/null 2>/dev/null; then + echo "alias rtrmon=\"sh /jffs/scripts/rtrmon.sh\" # RTRMON" >> /jffs/configs/profile.add + fi + + while true + do + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} RTRMON Main Setup and Configuration Menu ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please choose from the various options below, which allow you to perform high level${CClear}" + echo -e "${InvGreen} ${CClear} actions in the management of the RTRMON script.${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(1)${CClear} : Setup and Configure RTRMON" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(2)${CClear} : Force Re-install Entware Dependencies" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(3)${CClear} : Check for latest updates" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(4)${CClear} : View logs" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(5)${CClear} : Uninstall" + if [ "$FromUI" == "0" ]; then + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite} | ${CClear}" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(6)${CClear} : Launch RTRMON into Normal Monitoring Mode" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(7)${CClear} : Launch RTRMON into Normal Monitoring Mode w/ SCREEN" + fi + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite} | ${CClear}" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(e)${CClear} : Exit" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + if [ "$FromUI" == "0" ]; then + read -p "Please select? (1-7, e=Exit): " InstallSelection + else + read -p "Please select? (1-5, e=Exit): " InstallSelection + fi + + # Execute chosen selections + case "$InstallSelection" in + + 1) # Check for existence of entware, and if so proceed and install the timeout package, then run RTRMON -config + clear + if [ -f "/opt/bin/column" ] && [ -f "/opt/bin/timeout" ] && [ -f "/opt/sbin/screen" ] && [ -f "/opt/bin/nmap" ] && [ -f "/opt/bin/jq" ] && [ -f "/opt/bin/iftop" ] + then + vconfig + else + echo -e "${InvGreen} ${InvDkGray}${CWhite} Install Dependencies ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Missing dependencies required by RTRMON will be installed during this process." + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "RTRMON will require the installation of CoreUtils-Timeout, Screen and Nmap utilities." + echo -e "These utilities require you to have Entware already installed using the AMTM tool. If" + echo -e "Entware is present, the Timeout, Screen and Nmap utilities will be downloaded and" + echo -e "installed during this setup process, and utilized by RTRMON." + echo "" + echo -e "${CGreen}CoreUtils-Timeout${CClear} is a utility that provides more stability for certain routers (like" + echo -e "the RT-AC86U) which has a tendency to randomly hang scripts running on this router model." + echo "" + echo -e "${CGreen}Screen${CClear} is a utility that allows you to run SSH scripts in a standalone" + echo -e "environment directly on the router itself, instead of running your commands or a script" + echo -e "from a network-attached SSH client. This can provide greater stability due to it running" + echo -e "from the router itself." + echo "" + echo -e "${CGreen}Nmap${CClear} is a network discovery and security auditing tool that is used to scan your LAN," + echo -e "WAN and VPN connections for open ports." + echo "" + echo -e "${CGreen}JQuery${CClear} is a utility for querying data across the internet for the purposes of" + echo -e "interacting with the various VPN providers to get a list of APIs available VPN hosts in" + echo -e "the selected country." + echo "" + echo -e "${CGreen}iftop${CClear} is a utility for querying connection and bandwidth data." + echo "" + echo -e "${CGreen}Column${CClear} is a utility used to neatly arrange data on screen." + echo "" + echo -e "Your router model is: ${CGreen}${RouterModel}${CClear}" + echo "" + echo -e "Ready to install?" + if promptyn "[y/n]: " + then + if [ -d "/opt" ]; then # Does entware exist? If yes proceed, if no error out. + echo "" + echo -e "\n${CClear}Updating Entware Packages..." + echo "" + opkg update + echo "" + echo -e "Installing Entware ${CGreen}CoreUtils-Timeout${CClear} Package..." + echo "" + opkg install coreutils-timeout + echo "" + echo -e "Installing Entware ${CGreen}Screen Package${CClear}..." + echo "" + opkg install screen + echo "" + echo -e "Installing Entware ${CGreen}Nmap${CClear} Package..." + echo "" + opkg install nmap + echo "" + echo -e "Installing Entware ${CGreen}JQuery${CClear} Package..." + echo "" + opkg install jq + echo "" + echo -e "Installing Entware ${CGreen}iftop${CClear} Package..." + echo "" + opkg install iftop + echo "" + echo -e "Installing Entware ${CGreen}Column${CClear} Package..." + echo "" + opkg install column + echo "" + echo -e "Install completed..." + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: Entware dependencies were successfully installed." >> $LOGFILE + echo "" + read -rsp $'Press any key to continue...\n' -n1 key + echo "" + echo -e "Executing RTRMON Configuration Utility..." + sleep 2 + vconfig + else + clear + echo -e "${CRed}ERROR: Entware was not found on this router...${CClear}" + echo -e "Please install Entware using the AMTM utility before proceeding..." + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - ERROR: Entware was not found on this router. Please install using AMTM utility." >> $LOGFILE + echo "" + sleep 3 + fi + else + echo "" + echo -e "\nExecuting RTRMON Configuration Utility..." + sleep 2 + vconfig + fi + fi + ;; + + + 2) # Force re-install the CoreUtils timeout/screen package + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Re-install Dependencies ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Missing dependencies required by RTRMON will be re-installed during this process." + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "VPNMON-R3 has some dependencies in order to function correctly, namely, CoreUtils-Timeout" + echo -e "RTRMON will require the installation of CoreUtils-Timeout, Screen, Nmap, JQ and iftop" + echo -e "utilities. These utilities require you to have Entware already installed using AMTM. If" + echo -e "Entware is present, the Timeout, Screen, Nmap, JQ and iftop utilities will be downloaded" + echo -e "and re-installed during this setup process, and utilized by RTRMON." + echo "" + echo -e "${CGreen}CoreUtils-Timeout${CClear} is a utility that provides more stability for certain routers (like" + echo -e "the RT-AC86U) which has a tendency to randomly hang scripts running on this router model." + echo "" + echo -e "${CGreen}Screen${CClear} is a utility that allows you to run SSH scripts in a standalone" + echo -e "environment directly on the router itself, instead of running your commands or a script" + echo -e "from a network-attached SSH client. This can provide greater stability due to it running" + echo -e "from the router itself." + echo "" + echo -e "${CGreen}Nmap${CClear} is a network discovery and security auditing tool that is used to scan your LAN," + echo -e "WAN and VPN connections for open ports." + echo "" + echo -e "${CGreen}JQuery${CClear} is a utility for querying data across the internet for the purposes of" + echo -e "interacting with the various VPN providers to get a list of APIs available VPN hosts in" + echo -e "the selected country." + echo "" + echo -e "${CGreen}iftop${CClear} is a utility for querying connection and bandwidth data." + echo "" + echo -e "${CGreen}Column${CClear} is a utility used to neatly arrange data on screen." + echo "" + echo -e "Your router model is: ${CGreen}${RouterModel}${CClear}" + echo "" + echo -e "Force Re-install?" + if promptyn "[y/n]: " + then + if [ -d "/opt" ]; then # Does entware exist? If yes proceed, if no error out. + echo "" + echo -e "\n${CClear}Updating Entware Packages..." + echo "" + opkg update + echo "" + echo -e "Force Re-installing Entware ${CGreen}CoreUtils-Timeout${CClear} Package..." + echo "" + opkg install --force-reinstall coreutils-timeout + echo "" + echo -e "Force Re-installing Entware ${CGreen}Screen${CClear} Package..." + echo "" + opkg install --force-reinstall screen + echo "" + echo -e "Force Re-installing Entware ${CGreen}Nmap${CClear} Package..." + echo "" + opkg install --force-reinstall nmap + echo "" + echo -e "Force Re-installing Entware ${CGreen}JQuery${CClear} Package..." + echo "" + opkg install --force-reinstall jq + echo "" + echo -e "Force Re-installing Entware ${CGreen}iftop${CClear} Package..." + echo "" + opkg install --force-reinstall iftop + echo "" + echo -e "Force Re-installing Entware ${CGreen}Column${CClear} Package..." + echo "" + opkg install --force-reinstall column + echo "" + echo -e "Re-install completed..." + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: Entware dependencies were successfully re-installed." >> $LOGFILE + echo "" + read -rsp $'Press any key to continue...\n' -n1 key + else + clear + echo -e "${CRed}ERROR: Entware was not found on this router...${CClear}" + echo -e "Please install Entware using the AMTM utility before proceeding..." + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - ERROR: Entware was not found on this router. Please install using AMTM utility." >> $LOGFILE + echo "" + sleep 3 + fi + fi + ;; + + 3) + echo "" + vupdate + ;; + + 6) + echo "" + echo -e "\n${CGreen}Launching RTRMON into Monitor Mode...${CClear}" + sleep 2 + exec sh $APPPATH -monitor + ;; + + 7) + echo "" + echo -e "\n${CGreen}Launching RTRMON into Monitor Mode with Screen Utility...${CClear}" + sleep 2 + exec sh $APPPATH -screen + ;; + + 4) + echo "" + vlogs + ;; + + 5) + echo "" + vuninstall + ;; + + [Ee]) + echo -e "${CClear}" + timer="$Interval" + break + ;; + + *) + echo "" + echo -e "${CRed}Invalid choice - Please enter a valid option...${CClear}" + echo "" + sleep 2 + ;; + + esac + done +} + +# ------------------------------------------------------------------------------------------------------------------------- + +# get_wan_setting was "borrowed" graciously from @dave14305 from his FlexQoS script to determine the active WAN connection. +# Thanks much for your troubleshooting help as we tackled how to best derive the active WAN interface, Dave! +get_wan_setting() { + local varname varval + varname="${1}" + prefixes="wan0_ wan1_" + + if [ "$($timeoutcmd$timeoutsec nvram get wans_mode)" = "lb" ] ; then + for prefix in $prefixes; do + state="$($timeoutcmd$timeoutsec nvram get "${prefix}"state_t)" + sbstate="$($timeoutcmd$timeoutsec nvram get "${prefix}"sbstate_t)" + auxstate="$($timeoutcmd$timeoutsec nvram get "${prefix}"auxstate_t)" + + # is_wan_connect() + [ "${state}" = "2" ] || continue + [ "${sbstate}" = "0" ] || continue + [ "${auxstate}" = "0" ] || [ "${auxstate}" = "2" ] || continue + + # get_wan_ifname() + proto="$($timeoutcmd$timeoutsec nvram get "${prefix}"proto)" + if [ "${proto}" = "pppoe" ] || [ "${proto}" = "pptp" ] || [ "${proto}" = "l2tp" ] ; then + varval="$($timeoutcmd$timeoutsec nvram get "${prefix}"pppoe_"${varname}")" + else + varval="$($timeoutcmd$timeoutsec nvram get "${prefix}""${varname}")" + fi + done + else + for prefix in $prefixes; do + primary="$($timeoutcmd$timeoutsec nvram get "${prefix}"primary)" + [ "${primary}" = "1" ] && break + done + + proto="$($timeoutcmd$timeoutsec nvram get "${prefix}"proto)" + if [ "${proto}" = "pppoe" ] || [ "${proto}" = "pptp" ] || [ "${proto}" = "l2tp" ] ; then + varval="$($timeoutcmd$timeoutsec nvram get "${prefix}"pppoe_"${varname}")" + else + varval="$($timeoutcmd$timeoutsec nvram get "${prefix}""${varname}")" + fi + fi + printf "%s" "${varval}" +} # get_wan_setting + +# ------------------------------------------------------------------------------------------------------------------------- + +# gettopstats gathers the majority of cpu and memory related stats directly from the TOP utility +##----------------------------------------## +## Modified by Martinski W. [2024-Nov-02] ## +##----------------------------------------## +gettopstats () +{ + local numFields + + TotalMem="$(top -bn1 | head -n3 | grep -E '^Mem:|^CPU:|^Load' | awk 'NR==1 {print $2, $4, $6, $8, $10} NR==2 {print $2, $4, $6, $8, $14} NR==3 {print $3, $4, $5}' 2>/dev/null)" + + numFields="$(echo $TotalMem | awk -F ' ' '{print NF}')" + [ "$numFields" -lt 13 ] && return 1 + + #totalmemory based on the power of 2 to determine nearest estimated installed RAM + memtotal="$(awk '/^MemTotal:/ {print $2}' /proc/meminfo)" + totalreportedphysmem=$(awk 'BEGIN { printf "%.0f", ('"$memtotal"' / 1000) }') + next_power_of_2=$(awk -v num="$totalreportedphysmem" ' + BEGIN { + if (num == 0) { + print 1; + exit; + } + num--; + num = or(num, rshift(num, 1)); + num = or(num, rshift(num, 2)); + num = or(num, rshift(num, 4)); + num = or(num, rshift(num, 8)); + num = or(num, rshift(num, 16)); + # num = or(num, rshift(num, 32)); + num++; + print num; + } + ') + totalmemory="$next_power_of_2" + + memfree="$(awk '/^MemFree:/ {print $2}' /proc/meminfo)" + membuff="$(awk '/^Buffers:/ {print $2}' /proc/meminfo)" + memcach="$(awk '/^Cached:/ {print $2}' /proc/meminfo)" + memfree="$(awk 'BEGIN { printf "%.0f", ('"$memfree"' + '"$membuff"' + '"$memcach"') }')" + memshrd="$(awk '/^Shmem:/ {print $2}' /proc/meminfo)" + memused="$(awk 'BEGIN { printf "%.0f", ('"$totalmemory"' * 1000 - '"$memfree"') }')" + + cpuusr="$(echo $TotalMem | awk '{print $6}' | sed 's/%$//' | cut -d . -f 1)" + cpusys="$(echo $TotalMem | awk '{print $7}' | sed 's/%$//' | cut -d . -f 1)" + cpunice="$(echo $TotalMem | awk '{print $8}' | sed 's/%$//' | cut -d . -f 1)" + cpuidle="$(echo $TotalMem | awk '{print $9}' | sed 's/%$//' | cut -d . -f 1)" + cpuirq="$(echo $TotalMem | awk '{print $10}' | sed 's/%$//' | cut -d . -f 1)" + displaycpuusr="$(echo $TotalMem | awk '{print $6}' | sed 's/%$//')" + displaycpusys="$(echo $TotalMem | awk '{print $7}' | sed 's/%$//')" + displaycpunice="$(echo $TotalMem | awk '{print $8}' | sed 's/%$//')" + displaycpuidle="$(echo $TotalMem | awk '{print $9}' | sed 's/%$//')" + displaycpuirq="$(echo $TotalMem | awk '{print $10}' | sed 's/%$//')" + cpuload1m="$(echo $TotalMem | awk '{print $11}')" + cpuload5m="$(echo $TotalMem | awk '{print $12}')" + cpuload15m="$(echo $TotalMem | awk '{print $13}')" + + memused1="$((memused1 + memused))" + memfree1="$((memfree1 + memfree))" + memshrd1="$((memshrd1 + memshrd))" + membuff1="$((membuff1 + membuff))" + memcach1="$((memcach1 + memcach))" + cpuusr1="$((cpuusr1 + cpuusr))" + cpusys1="$((cpusys1 + cpusys))" + cpunice1="$((cpunice1 + cpunice))" + cpuidle1="$((cpuidle1 + cpuidle))" + cpuirq1="$((cpuirq1 + cpuirq))" + + displaycpuusr1="$(awk -v v1=$displaycpuusr1 -v v2=$displaycpuusr 'BEGIN{printf "%0.2f\n", v1+v2}')" + displaycpusys1="$(awk -v v1=$displaycpusys1 -v v2=$displaycpusys 'BEGIN{printf "%0.2f\n", v1+v2}')" + displaycpunice1="$(awk -v v1=$displaycpunice1 -v v2=$displaycpunice 'BEGIN{printf "%0.2f\n", v1+v2}')" + displaycpuidle1="$(awk -v v1=$displaycpuidle1 -v v2=$displaycpuidle 'BEGIN{printf "%0.2f\n", v1+v2}')" + displaycpuirq1="$(awk -v v1=$displaycpuirq1 -v v2=$displaycpuirq 'BEGIN{printf "%0.2f\n", v1+v2}')" + + return 0 +} + +# ------------------------------------------------------------------------------------------------------------------------- + +# oldstats holds the old (current) stats that are being used to display stats on-screen +oldstats() +{ + oldcpuusr1=$cpuusr1 + oldcpusys1=$cpusys1 + oldcpunice1=$cpunice1 + oldcpuidle1=$cpuidle1 + oldcpuirq1=$cpuirq1 + olddisplaycpuusr1=$displaycpuusr1 + olddisplaycpusys1=$displaycpusys1 + olddisplaycpunice1=$displaycpunice1 + olddisplaycpuidle1=$displaycpuidle1 + olddisplaycpuirq1=$displaycpuirq1 + oldF_cputemp=$F_cputemp + oldmemused2=$memused2 + oldmemfree2=$memfree2 + oldmemshrd2=$memshrd2 + oldmembuff2=$membuff2 + oldmemcach2=$memcach2 + oldtotalmemory=$totalmemory + oldnvramfree=$nvramfree + oldnvramused=$nvramused + oldtotalnvram=$totalnvram + oldjffstotal=$jffstotal + oldjffsused=$jffsused + oldswaptotal=$swaptotal + oldswapused=$swapused + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + oldwan0ip=$wan0ip + oldwan1ip=$wan1ip + fi + olddns1ip=$dns1ip + olddns2ip=$dns2ip + oldwanip6=$wanip6 + oldlanip6=$lanip6 + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + oldwanrxmbrate=$wanrxmbrate + oldwantxmbrate=$wantxmbrate + fi + oldw24rxmbrate=$w24rxmbrate + oldw24txmbrate=$w24txmbrate + oldw5rxmbrate=$w5rxmbrate + oldw5txmbrate=$w5txmbrate + oldw24temp=$w24temp + oldw5temp=$w5temp + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then + oldw52rxmbrate=$w52rxmbrate + oldw52txmbrate=$w52txmbrate + oldw52temp=$w52temp + fi + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then + oldw6rxmbrate=$w6rxmbrate + oldw6txmbrate=$w6txmbrate + oldw6temp=$w6temp + fi + if [ "$FourBandCustom56624" == "True" ]; then + oldw62rxmbrate=$w62rxmbrate + oldw62txmbrate=$w62txmbrate + oldw62temp=$w62temp + fi + + oldlanip=$lanip + oldlanrxmbrate=$lanrxmbrate + oldlantxmbrate=$lantxmbrate + + oldvpnrxmbrate=$vpnrxmbrate + oldvpntxmbrate=$vpntxmbrate + oldvpn2rxmbrate=$vpn2rxmbrate + oldvpn2txmbrate=$vpn2txmbrate + oldvpn3rxmbrate=$vpn3rxmbrate + oldvpn3txmbrate=$vpn3txmbrate + oldvpn4rxmbrate=$vpn4rxmbrate + oldvpn4txmbrate=$vpn4txmbrate + oldvpn5rxmbrate=$vpn5rxmbrate + oldvpn5txmbrate=$vpn5txmbrate + oldvpn1ip=$vpn1ip + oldvpn1city=$vpn1city + oldvpn2ip=$vpn2ip + oldvpn2city=$vpn2city + oldvpn3ip=$vpn3ip + oldvpn3city=$vpn3city + oldvpn4ip=$vpn4ip + oldvpn4city=$vpn4city + oldvpn5ip=$vpn5ip + oldvpn5city=$vpn5city + + oldwg1rxmbrate=$wg1rxmbrate + oldwg1txmbrate=$wg1txmbrate + oldwg2rxmbrate=$wg2rxmbrate + oldwg2txmbrate=$wg2txmbrate + oldwg3rxmbrate=$wg3rxmbrate + oldwg3txmbrate=$wg3txmbrate + oldwg4rxmbrate=$wg4rxmbrate + oldwg4txmbrate=$wg4txmbrate + oldwg5rxmbrate=$wg5rxmbrate + oldwg5txmbrate=$wg5txmbrate + oldwg1ip=$wg1ip + oldwg1city=$wg1city + oldwg2ip=$wg2ip + oldwg2city=$wg2city + oldwg3ip=$wg3ip + oldwg3city=$wg3city + oldwg4ip=$wg4ip + oldwg4city=$wg4city + oldwg5ip=$wg5ip + oldwg5city=$wg5city + + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + oldwanrxmbratedisplay=$wanrxmbratedisplay + oldwantxmbratedisplay=$wantxmbratedisplay + fi + oldw24rxmbratedisplay=$w24rxmbratedisplay + oldw24txmbratedisplay=$w24txmbratedisplay + oldw5rxmbratedisplay=$w5rxmbratedisplay + oldw5txmbratedisplay=$w5txmbratedisplay + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then + oldw52rxmbratedisplay=$w52rxmbratedisplay + oldw52txmbratedisplay=$w52txmbratedisplay + fi + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then + oldw6rxmbratedisplay=$w6rxmbratedisplay + oldw6txmbratedisplay=$w6txmbratedisplay + fi + if [ "$FourBandCustom56624" == "True" ]; then + oldw62rxmbratedisplay=$w62rxmbratedisplay + oldw62txmbratedisplay=$w62txmbratedisplay + fi + oldlanrxmbratedisplay=$lanrxmbratedisplay + oldlantxmbratedisplay=$lantxmbratedisplay + + oldvpnrxmbratedisplay=$vpnrxmbratedisplay + oldvpntxmbratedisplay=$vpntxmbratedisplay + oldvpn2rxmbratedisplay=$vpn2rxmbratedisplay + oldvpn2txmbratedisplay=$vpn2txmbratedisplay + oldvpn3rxmbratedisplay=$vpn3rxmbratedisplay + oldvpn3txmbratedisplay=$vpn3txmbratedisplay + oldvpn4rxmbratedisplay=$vpn4rxmbratedisplay + oldvpn4txmbratedisplay=$vpn4txmbratedisplay + oldvpn5rxmbratedisplay=$vpn5rxmbratedisplay + oldvpn5txmbratedisplay=$vpn5txmbratedisplay + + oldwg1rxmbratedisplay=$wg1rxmbratedisplay + oldwg1txmbratedisplay=$wg1txmbratedisplay + oldwg2rxmbratedisplay=$wg2rxmbratedisplay + oldwg2txmbratedisplay=$wg2txmbratedisplay + oldwg3rxmbratedisplay=$wg3rxmbratedisplay + oldwg3txmbratedisplay=$wg3txmbratedisplay + oldwg4rxmbratedisplay=$wg4rxmbratedisplay + oldwg4txmbratedisplay=$wg4txmbratedisplay + oldwg5rxmbratedisplay=$wg5rxmbratedisplay + oldwg5txmbratedisplay=$wg5txmbratedisplay +} + +# ------------------------------------------------------------------------------------------------------------------------- +##----------------------------------------## +## Modified by Martinski W. [2024-Nov-04] ## +##----------------------------------------## +# Calculates and captures, well, all the current stats from their sources ;) +calculatestats() +{ + + RM_END_TIME="$(date +%s)" + RM_ELAPSED_TIME=$((RM_END_TIME - RM_START_TIME)) + [ "$RM_ELAPSED_TIME" -eq 0 ] && return 1 + + # CPU - Usage + if [ -n "$cpuusr1" ]; then cpuusr1=$((cpuusr1 / Interval)); else cpuusr1=0; fi + if [ -n "$cpusys1" ]; then cpusys1=$((cpusys1 / Interval)); else cpusys1=0; fi + if [ -n "$cpunice1" ]; then cpunice1=$((cpunice1 / Interval)); else cpunice1=0; fi + if [ -n "$cpuidle1" ]; then cpuidle1=$((cpuidle1 / Interval)); else cpuidle1=0; fi + if [ -n "$cpuirq1" ]; then cpuirq1=$((cpuirq1 / Interval)); else cpuirq1=0; fi + if [ -n "$displaycpuusr1" ]; then displaycpuusr1=$(awk -v rb=$displaycpuusr1 -v intv=$Interval 'BEGIN{printf "%0.2f\n", rb/intv}'); else displaycpuusr1=0; fi + if [ -n "$displaycpusys1" ]; then displaycpusys1=$(awk -v rb=$displaycpusys1 -v intv=$Interval 'BEGIN{printf "%0.2f\n", rb/intv}'); else displaycpusys1=0; fi + if [ -n "$displaycpunice1" ]; then displaycpunice1=$(awk -v rb=$displaycpunice1 -v intv=$Interval 'BEGIN{printf "%0.2f\n", rb/intv}'); else displaycpunice1=0; fi + if [ -n "$displaycpuidle1" ]; then displaycpuidle1=$(awk -v rb=$displaycpuidle1 -v intv=$Interval 'BEGIN{printf "%0.2f\n", rb/intv}'); else displaycpuidle1=0; fi + if [ -n "$displaycpuirq1" ]; then displaycpuirq1=$(awk -v rb=$displaycpuirq1 -v intv=$Interval 'BEGIN{printf "%0.2f\n", rb/intv}'); else displaycpuirq1=0; fi + + # CPU - Temp - borrowed from @Maverickcdn - thank you! + if [ -f /sys/class/thermal/thermal_zone0/temp ]; then + F_cputemp=$($timeoutcmd$timeoutsec cat /sys/class/thermal/thermal_zone0/temp | cut -c -2) + elif [ -f /proc/dmu/temperature ]; then # Thanks to PeterR for the bug report on AC68U's - hopefully this will fix that + F_cputemp=$($timeoutcmd$timeoutsec cat /proc/dmu/temperature | cut -c19-20) + fi + + # Memory - Usage + if [ -n "$memused1" ]; then memused1=$((memused1 / Interval)); else memused1=0; fi + if [ -n "$memfree1" ]; then memfree1=$((memfree1 / Interval)); else memfree1=0; fi + if [ -n "$memshrd1" ]; then memshrd1=$((memshrd1 / Interval)); else memshrd1=0; fi + if [ -n "$membuff1" ]; then membuff1=$((membuff1 / Interval)); else membuff1=0; fi + if [ -n "$memcach1" ]; then memcach1=$((memcach1 / Interval)); else memcach1=0; fi + + totalphysmem="$totalmemory" + + memused2=$(awk 'BEGIN { printf "%.0f", ('"$memused1"' / 1000) }') + memfree2=$(awk 'BEGIN { printf "%.0f", ('"$memfree1"' / 1000) }') + memshrd2=$(awk 'BEGIN { printf "%.0f", ('"$memshrd1"' / 1000) }') + membuff2=$(awk 'BEGIN { printf "%.0f", ('"$membuff1"' / 1000) }') + memcach2=$(awk 'BEGIN { printf "%.0f", ('"$memcach1"' / 1000) }') + + # Memory - NVRAM -- Many thanks to @RMerlin, @SomewhereOverTheRainbow and @Ranger802004 for your help finding NVRAM stats + eval "$($timeoutcmd$timeoutsec nvram show >/tmp/output.txt 2> /tmp/size.txt)" + chmod 755 /tmp/size.txt + nvramtotals=$(cat /tmp/size.txt | grep size: | awk '{print $2, $4}' 2>/dev/null) + nvramused="$(echo $nvramtotals | awk '{print $1}')" + nvramfree="$(echo $nvramtotals | awk '{print $2}' | sed 's/[)(]//g')" + if [ -z $nvramused ] || [ -z $nvramfree ]; then + nvramused=10000 # incase the values coming back from this file are blank, use temporary fillers + totalnvram=20000 + else + totalnvram="$((nvramused + nvramfree))" + fi + + # Disk - JFFS + disk_use=$($timeoutcmd$timeoutsec df -P | grep -E '/jffs' | awk '{print $2, $3}') + jffstotal="$(echo $disk_use | awk '{print $1}')" + jffsused="$(echo $disk_use | awk '{print $2}')" + jffstotal=$(awk 'BEGIN { printf "%.0f", ('"$jffstotal"' / 1000) }') + jffsused=$(awk 'BEGIN { printf "%.0f", ('"$jffsused"' / 1000) }') + + # Disk - Swap file + swap_use=$($timeoutcmd$timeoutsec /usr/bin/free | awk 'NR==4 {print $2, $3}' 2>/dev/null) + swaptotal="$(echo $swap_use | awk '{print $1}')" + swapused="$(echo $swap_use | awk '{print $2}')" + swaptotal=$(awk 'BEGIN { printf "%.0f", ('"$swaptotal"' / 1000) }') + swapused=$(awk 'BEGIN { printf "%.0f", ('"$swapused"' / 1000) }') + if [ $swaptotal == "0" ]; then swaptotal=100; fi + + # Disk - SD devices + df | grep /dev/sd > /jffs/addons/rtrmon.d/sdresult.txt 2>/dev/null + + # Network - WAN/LAN/DNS IP Addresses + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ] + then + wan0ip=$($timeoutcmd$timeoutsec nvram get wan0_ipaddr) + wan1ip=$($timeoutcmd$timeoutsec nvram get wan1_ipaddr) + fi + lanip=$($timeoutcmd$timeoutsec nvram get lan_ipaddr) + dns1ip="$($timeoutcmd$timeoutsec nvram get wan0_dns | awk '{print $1}')" + dns2ip="$($timeoutcmd$timeoutsec nvram get wan0_dns | awk '{print $2}')" + dns3ip="$($timeoutcmd$timeoutsec nvram get wan1_dns | awk '{print $1}')" + dns4ip="$($timeoutcmd$timeoutsec nvram get wan1_dns | awk '{print $2}')" + + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ] + then + if [ -z $wan0ip ]; then dns1ip="0.0.0.0"; fi + if [ -z $wan1ip ]; then dns1ip="0.0.0.0"; fi + fi + if [ -z $lanip ]; then dns1ip="0.0.0.0"; fi + if [ -z $dns1ip ]; then dns1ip="0.0.0.0"; fi + if [ -z $dns2ip ]; then dns2ip="0.0.0.0"; fi + if [ $dns1ip == "0.0.0.0" ] && [ ! -z $dns3ip ]; then dns1ip=$dns3ip; fi + if [ $dns2ip == "0.0.0.0" ] && [ ! -z $dns4ip ]; then dns2ip=$dns4ip; fi + if [ "$vpn1on" == "False" ]; then vpn1ip="0.0.0.0"; fi + if [ "$vpn2on" == "False" ]; then vpn2ip="0.0.0.0"; fi + if [ "$vpn3on" == "False" ]; then vpn3ip="0.0.0.0"; fi + if [ "$vpn4on" == "False" ]; then vpn4ip="0.0.0.0"; fi + if [ "$vpn5on" == "False" ]; then vpn5ip="0.0.0.0"; fi + if [ "$wg1on" == "False" ]; then wg1ip="0.0.0.0"; fi + if [ "$wg2on" == "False" ]; then wg2ip="0.0.0.0"; fi + if [ "$wg3on" == "False" ]; then wg3ip="0.0.0.0"; fi + if [ "$wg4on" == "False" ]; then wg4ip="0.0.0.0"; fi + if [ "$wg5on" == "False" ]; then wg5ip="0.0.0.0"; fi + + # Many thanks to @SomewhereOverTheRainbow for his help and suggestions on getting IP6 info! + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + wanip6="$(ip -o -6 addr list "$WANIFNAME" scope global | awk 'NR==1{ split($4, ip_addr, "/"); print ip_addr[1] }')" + fi + lanip6="$(ip -o -6 addr list br0 scope global | awk 'NR==1{ split($4, ip_addr, "/"); print ip_addr[1] }')" + + # Network - Wifi - Temp + # Standard Dual-Band config + w24tempraw=$($timeoutcmd$timeoutsec wl -i $ifname24 phy_tempsense | awk '{print $1}' ) >/dev/null 2>&1 + w5tempraw=$($timeoutcmd$timeoutsec wl -i $ifname5 phy_tempsense | awk '{print $1}' ) >/dev/null 2>&1 + if [ -z $w24tempraw ] || [ $w24tempraw -eq 0 ]; then w24tempraw=1; fi #in case it does not return a valid number + if [ -z $w5tempraw ] || [ $w5tempraw -eq 0 ]; then w5tempraw=1; fi + w24temp=$(awk -v v1=$w24tempraw 'BEGIN{printf "\n" (v1/2)+20}' | cut -d . -f 1) + w5temp=$(awk -v v1=$w5tempraw 'BEGIN{printf "\n" (v1/2)+20}' | cut -d . -f 1) + + # Tri or Quad Band 5GHz + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then + w52tempraw=$($timeoutcmd$timeoutsec wl -i $ifname52 phy_tempsense | awk '{print $1}' ) >/dev/null 2>&1 + if [ -z $w52tempraw ] || [ $w52tempraw -eq 0 ]; then w52tempraw=1; fi + w52temp=$(awk -v v1=$w52tempraw 'BEGIN{printf "\n" (v1/2)+20}' | cut -d . -f 1) + fi + # Tri or Quad-Band 6GHz + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then + w6tempraw=$($timeoutcmd$timeoutsec wl -i $ifname6 phy_tempsense | awk '{print $1}' ) >/dev/null 2>&1 + if [ -z $w6tempraw ] || [ $w6tempraw -eq 0 ]; then w6tempraw=1; fi + w6temp=$(awk -v v1=$w6tempraw 'BEGIN{printf "\n" (v1/2)+20}' | cut -d . -f 1) + fi + if [ "$FourBandCustom56624" == "True" ]; then + w62tempraw=$($timeoutcmd$timeoutsec wl -i $ifname62 phy_tempsense | awk '{print $1}' ) >/dev/null 2>&1 + if [ -z $w62tempraw ] || [ $w62tempraw -eq 0 ]; then w62tempraw=1; fi + w62temp=$(awk -v v1=$w62tempraw 'BEGIN{printf "\n" (v1/2)+20}' | cut -d . -f 1) + fi + + # Network - Wifi - Up/Down via Scheduler + if [ "$FourBandCustom55624" == "True" ]; then + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl0_sched_v2) ]; then w5udsched="Scheduler[+]"; else w5udsched="Scheduler[-]"; fi + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl1_sched_v2) ]; then w52udsched="Scheduler[+]"; else w52udsched="Scheduler[-]"; fi + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl2_sched_v2) ]; then w6udsched="Scheduler[+]"; else w6udsched="Scheduler[-]"; fi + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl3_sched_v2) ]; then w24udsched="Scheduler[+]"; else w24udsched="Scheduler[-]"; fi + elif [ "$FourBandCustom56624" == "True" ]; then + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl0_sched_v2) ]; then w5udsched="Scheduler[+]"; else w5udsched="Scheduler[-]"; fi + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl1_sched_v2) ]; then w6udsched="Scheduler[+]"; else w6udsched="Scheduler[-]"; fi + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl2_sched_v2) ]; then w62udsched="Scheduler[+]"; else w62udsched="Scheduler[-]"; fi + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl3_sched_v2) ]; then w24udsched="Scheduler[+]"; else w24udsched="Scheduler[-]"; fi + elif [ "$ThreeBand2456" == "True" ]; then + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl0_sched_v2) ]; then w24udsched="Scheduler[+]"; else w24udsched="Scheduler[-]"; fi + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl1_sched_v2) ]; then w5udsched="Scheduler[+]"; else w5udsched="Scheduler[-]"; fi + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl2_sched_v2) ]; then w6udsched="Scheduler[+]"; else w6udsched="Scheduler[-]"; fi + elif [ "$ThreeBand2455" == "True" ]; then + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl0_sched_v2) ]; then w24udsched="Scheduler[+]"; else w24udsched="Scheduler[-]"; fi + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl1_sched_v2) ]; then w5udsched="Scheduler[+]"; else w5udsched="Scheduler[-]"; fi + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl2_sched_v2) ]; then w52udsched="Scheduler[+]"; else w52udsched="Scheduler[-]"; fi + else + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl0_sched_v2) ]; then w24udsched="Scheduler[+]"; else w24udsched="Scheduler[-]"; fi + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl1_sched_v2) ]; then w5udsched="Scheduler[+]"; else w5udsched="Scheduler[-]"; fi + fi + + w24updown=$($timeoutcmd$timeoutsec wl -i $ifname24 bss | awk '{print toupper($1)}' ) >/dev/null 2>&1 + w5updown=$($timeoutcmd$timeoutsec wl -i $ifname5 bss | awk '{print toupper($1)}' ) >/dev/null 2>&1 + if [ -z "$w24updown" ]; then w24updown="UP"; fi + if [ -z "$w5updown" ]; then w5updown="UP"; fi + + # Tri or Quad Band 5GHz + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then + w52updown=$($timeoutcmd$timeoutsec wl -i $ifname52 bss | awk '{print toupper($1)}' ) >/dev/null 2>&1 + if [ -z "$w52updown" ]; then w52updown="UP"; fi + fi + # Tri or Quad-Band 6GHz + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then + w6updown=$($timeoutcmd$timeoutsec wl -i $ifname6 bss | awk '{print toupper($1)}' ) >/dev/null 2>&1 + if [ -z $w6updown ]; then w6updown="UP"; fi + fi + if [ "$FourBandCustom56624" == "True" ]; then + w62updown=$($timeoutcmd$timeoutsec wl -i $ifname62 bss | awk '{print toupper($1)}' ) >/dev/null 2>&1 + if [ -z $w62updown ]; then w62updown="UP"; fi + fi + + # Network - Wifi - Traffic + # Standard Dual Band + new24rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname24/statistics/rx_bytes)" + new24txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname24/statistics/tx_bytes)" + new5rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname5/statistics/rx_bytes)" + new5txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname5/statistics/tx_bytes)" + + # Tri or Quad Band 5GHz + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ] + then + new52rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname52/statistics/rx_bytes)" + new52txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname52/statistics/tx_bytes)" + fi + # Tri or Quad Band 6GHz + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ] + then + new6rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname6/statistics/rx_bytes)" + new6txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname6/statistics/tx_bytes)" + fi + if [ "$FourBandCustom56624" == "True" ] + then + new62rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname62/statistics/rx_bytes)" + new62txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname62/statistics/tx_bytes)" + fi + + # Network - LAN - Traffic + newlanrxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/br0/statistics/rx_bytes)" + newlantxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/br0/statistics/tx_bytes)" + + # Network - WAN - Traffic + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ] + then + if [ $WANOverride == "Auto" ]; then WANIFNAME=$(get_wan_setting ifname); else WANIFNAME=$WANOverride; fi + newwanrxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$WANIFNAME/statistics/rx_bytes)" + newwantxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$WANIFNAME/statistics/tx_bytes)" + fi + + # Grab total bytes VPN Traffic Measurement + if [ "$vpn1on" == "True" ]; then + newvpntxrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn1slot/status 2>/dev/null) + newvpnrxbytes="$(echo $newvpntxrxbytes | cut -d' ' -f1)" + newvpntxbytes="$(echo $newvpntxrxbytes | cut -d' ' -f2)" + if [ -z $newvpnrxbytes ]; then newvpnrxbytes=0; fi + if [ -z $newvpntxbytes ]; then newvpntxbytes=0; fi + + if [ $newvpnrxbytes -le 0 ]; then + newvpnrxbytes=0 + elif [ $newvpntxbytes -le 0 ]; then + newvpntxbytes=0 + fi + fi + + if [ "$vpn2on" == "True" ]; then + newvpn2txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn2slot/status 2>/dev/null) + newvpn2rxbytes="$(echo $newvpn2txrxbytes | cut -d' ' -f1)" + newvpn2txbytes="$(echo $newvpn2txrxbytes | cut -d' ' -f2)" + if [ -z $newvpn2rxbytes ]; then newvpn2rxbytes=0; fi + if [ -z $newvpn2txbytes ]; then newvpn2txbytes=0; fi + + if [ $newvpn2rxbytes -le 0 ]; then + newvpn2rxbytes=0 + elif [ $newvpn2txbytes -le 0 ]; then + newvpn2txbytes=0 + fi + fi + + if [ "$vpn3on" == "True" ]; then + newvpn3txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn3slot/status 2>/dev/null) + newvpn3rxbytes="$(echo $newvpn3txrxbytes | cut -d' ' -f1)" + newvpn3txbytes="$(echo $newvpn3txrxbytes | cut -d' ' -f2)" + if [ -z $newvpn3rxbytes ]; then newvpn3rxbytes=0; fi + if [ -z $newvpn3txbytes ]; then newvpn3txbytes=0; fi + + if [ $newvpn3rxbytes -le 0 ]; then + newvpn3rxbytes=0 + elif [ $newvpn3txbytes -le 0 ]; then + newvpn3txbytes=0 + fi + fi + + if [ "$vpn4on" == "True" ]; then + newvpn4txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn4slot/status 2>/dev/null) + newvpn4rxbytes="$(echo $newvpn4txrxbytes | cut -d' ' -f1)" + newvpn4txbytes="$(echo $newvpn4txrxbytes | cut -d' ' -f2)" + if [ -z $newvpn4rxbytes ]; then newvpn4rxbytes=0; fi + if [ -z $newvpn4txbytes ]; then newvpn4txbytes=0; fi + + if [ $newvpn4rxbytes -le 0 ]; then + newvpn4rxbytes=0 + elif [ $newvpn4txbytes -le 0 ]; then + newvpn4txbytes=0 + fi + fi + + if [ "$vpn5on" == "True" ]; then + newvpn5txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn5slot/status 2>/dev/null) + newvpn5rxbytes="$(echo $newvpn5txrxbytes | cut -d' ' -f1)" + newvpn5txbytes="$(echo $newvpn5txrxbytes | cut -d' ' -f2)" + if [ -z $newvpn5rxbytes ]; then newvpn5rxbytes=0; fi + if [ -z $newvpn5txbytes ]; then newvpn5txbytes=0; fi + + if [ $newvpn5rxbytes -le 0 ]; then + newvpn5rxbytes=0 + elif [ $newvpn5txbytes -le 0 ]; then + newvpn5txbytes=0 + fi + fi + + # Check the wireguard connections + if [ "$wg1on" == "True" ]; then + newwg1txrxbytes=$(wg show wgc1 transfer) + newwg1rxbytes="$(echo $newwg1txrxbytes | cut -d' ' -f3)" + newwg1txbytes="$(echo $newwg1txrxbytes | cut -d' ' -f2)" + if [ -z $newwg1rxbytes ] || [ $newwg1rxbytes -le 0 ]; then newwg1rxbytes=0; fi + if [ -z $newwg1txbytes ] || [ $newwg1txbytes -le 0 ]; then newwg1txbytes=0; fi + fi + + if [ "$wg2on" == "True" ]; then + newwg2txrxbytes=$(wg show wgc2 transfer) + newwg2rxbytes="$(echo $newwg2txrxbytes | cut -d' ' -f3)" + newwg2txbytes="$(echo $newwg2txrxbytes | cut -d' ' -f2)" + if [ -z $newwg2rxbytes ] || [ $newwg2rxbytes -le 0 ]; then newwg2rxbytes=0; fi + if [ -z $newwg2txbytes ] || [ $newwg2txbytes -le 0 ]; then newwg2txbytes=0; fi + fi + + if [ "$wg3on" == "True" ]; then + newwg3txrxbytes=$(wg show wgc3 transfer) + newwg3rxbytes="$(echo $newwg3txrxbytes | cut -d' ' -f3)" + newwg3txbytes="$(echo $newwg3txrxbytes | cut -d' ' -f2)" + if [ -z $newwg3rxbytes ] || [ $newwg3rxbytes -le 0 ]; then newwg3rxbytes=0; fi + if [ -z $newwg3txbytes ] || [ $newwg3txbytes -le 0 ]; then newwg3txbytes=0; fi + fi + + if [ "$wg4on" == "True" ]; then + newwg4txrxbytes=$(wg show wgc4 transfer) + newwg4rxbytes="$(echo $newwg4txrxbytes | cut -d' ' -f3)" + newwg4txbytes="$(echo $newwg4txrxbytes | cut -d' ' -f2)" + if [ -z $newwg4rxbytes ] || [ $newwg4rxbytes -le 0 ]; then newwg4rxbytes=0; fi + if [ -z $newwg4txbytes ] || [ $newwg4txbytes -le 0 ]; then newwg4txbytes=0; fi + fi + + if [ "$wg5on" == "True" ]; then + newwg5txrxbytes=$(wg show wgc5 transfer) + newwg5rxbytes="$(echo $newwg5txrxbytes | cut -d' ' -f3)" + newwg5txbytes="$(echo $newwg5txrxbytes | cut -d' ' -f2)" + if [ -z $newwg5rxbytes ] || [ $newwg5rxbytes -le 0 ]; then newwg5rxbytes=0; fi + if [ -z $newwg5txbytes ] || [ $newwg5txbytes -le 0 ]; then newwg5txbytes=0; fi + fi + + # Network - Traffic - Calculations to find the difference between old and new total bytes send/received and divided to give Megabits + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + diffwanrxbytes=$(awk -v new=$newwanrxbytes -v old=$oldwanrxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diffwantxbytes=$(awk -v new=$newwantxbytes -v old=$oldwantxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + diff24rxbytes=$(awk -v new=$new24rxbytes -v old=$old24rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diff24txbytes=$(awk -v new=$new24txbytes -v old=$old24txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diff5rxbytes=$(awk -v new=$new5rxbytes -v old=$old5rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diff5txbytes=$(awk -v new=$new5txbytes -v old=$old5txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + difflanrxbytes=$(awk -v new=$newlanrxbytes -v old=$oldlanrxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + difflantxbytes=$(awk -v new=$newlantxbytes -v old=$oldlantxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then + diff52rxbytes=$(awk -v new=$new52rxbytes -v old=$old52rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diff52txbytes=$(awk -v new=$new52txbytes -v old=$old52txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then + diff6rxbytes=$(awk -v new=$new6rxbytes -v old=$old6rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diff6txbytes=$(awk -v new=$new6txbytes -v old=$old6txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + if [ "$FourBandCustom56624" == "True" ]; then + diff62rxbytes=$(awk -v new=$new62rxbytes -v old=$old62rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diff62txbytes=$(awk -v new=$new62txbytes -v old=$old62txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + if [ "$vpn1on" == "True" ]; then + diffvpnrxbytes=$(awk -v new=$newvpnrxbytes -v old=$oldvpnrxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diffvpntxbytes=$(awk -v new=$newvpntxbytes -v old=$oldvpntxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + if [ "$vpn2on" == "True" ]; then + diffvpn2rxbytes=$(awk -v new=$newvpn2rxbytes -v old=$oldvpn2rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diffvpn2txbytes=$(awk -v new=$newvpn2txbytes -v old=$oldvpn2txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + if [ "$vpn3on" == "True" ]; then + diffvpn3rxbytes=$(awk -v new=$newvpn3rxbytes -v old=$oldvpn3rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diffvpn3txbytes=$(awk -v new=$newvpn3txbytes -v old=$oldvpn3txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + if [ "$vpn4on" == "True" ]; then + diffvpn4rxbytes=$(awk -v new=$newvpn4rxbytes -v old=$oldvpn4rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diffvpn4txbytes=$(awk -v new=$newvpn4txbytes -v old=$oldvpn4txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + if [ "$vpn5on" == "True" ]; then + diffvpn5rxbytes=$(awk -v new=$newvpn5rxbytes -v old=$oldvpn5rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diffvpn5txbytes=$(awk -v new=$newvpn5txbytes -v old=$oldvpn5txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + if [ "$wg1on" == "True" ]; then + diffwg1rxbytes=$(awk -v new=$newwg1rxbytes -v old=$oldwg1rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diffwg1txbytes=$(awk -v new=$newwg1txbytes -v old=$oldwg1txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + if [ "$wg2on" == "True" ]; then + diffwg2rxbytes=$(awk -v new=$newwg2rxbytes -v old=$oldwg2rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diffwg2txbytes=$(awk -v new=$newwg2txbytes -v old=$oldwg2txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + if [ "$wg3on" == "True" ]; then + diffwg3rxbytes=$(awk -v new=$newwg3rxbytes -v old=$oldwg3rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diffwg3txbytes=$(awk -v new=$newwg3txbytes -v old=$oldwg3txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + if [ "$wg4on" == "True" ]; then + diffwg4rxbytes=$(awk -v new=$newwg4rxbytes -v old=$oldwg4rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diffwg4txbytes=$(awk -v new=$newwg4txbytes -v old=$oldwg4txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + if [ "$wg5on" == "True" ]; then + diffwg5rxbytes=$(awk -v new=$newwg5rxbytes -v old=$oldwg5rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diffwg5txbytes=$(awk -v new=$newwg5txbytes -v old=$oldwg5txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + + # Network - Traffic - Results are further divided by the timer/interval to give Megabits/sec + if [ "$WAN0AltModes" = "0" ] || [ "$OpsMode" = "1" ] + then + wanrxmbrate=$(awk -v rb=$diffwanrxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + wantxmbrate=$(awk -v tb=$diffwantxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + wanrxmbrate=0 + wantxmbrate=0 + fi + + w24rxmbrate=$(awk -v rb=$diff24rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + w24txmbrate=$(awk -v tb=$diff24txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + w5rxmbrate=$(awk -v rb=$diff5rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + w5txmbrate=$(awk -v tb=$diff5txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + lanrxmbrate=$(awk -v rb=$difflanrxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + lantxmbrate=$(awk -v tb=$difflantxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ] + then + w52rxmbrate=$(awk -v rb=$diff52rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + w52txmbrate=$(awk -v tb=$diff52txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + w52rxmbrate=0 + w52txmbrate=0 + fi + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ] + then + w6rxmbrate=$(awk -v rb=$diff6rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + w6txmbrate=$(awk -v tb=$diff6txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + w6rxmbrate=0 + w6txmbrate=0 + fi + if [ "$FourBandCustom56624" == "True" ] + then + w62rxmbrate=$(awk -v rb=$diff62rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + w62txmbrate=$(awk -v tb=$diff62txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + w62rxmbrate=0 + w62txmbrate=0 + fi + if [ "$vpn1on" == "True" ] + then + vpnrxmbrate=$(awk -v rb=$diffvpnrxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + vpntxmbrate=$(awk -v tb=$diffvpntxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + vpnrxmbrate=0 + vpntxmbrate=0 + fi + if [ "$vpn2on" == "True" ] + then + vpn2rxmbrate=$(awk -v rb=$diffvpn2rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + vpn2txmbrate=$(awk -v tb=$diffvpn2txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + vpn2rxmbrate=0 + vpn2txmbrate=0 + fi + if [ "$vpn3on" == "True" ] + then + vpn3rxmbrate=$(awk -v rb=$diffvpn3rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + vpn3txmbrate=$(awk -v tb=$diffvpn3txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + vpn3rxmbrate=0 + vpn3txmbrate=0 + fi + if [ "$vpn4on" == "True" ] + then + vpn4rxmbrate=$(awk -v rb=$diffvpn4rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + vpn4txmbrate=$(awk -v tb=$diffvpn4txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + vpn4rxmbrate=0 + vpn4txmbrate=0 + fi + if [ "$vpn5on" == "True" ] + then + vpn5rxmbrate=$(awk -v rb=$diffvpn5rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + vpn5txmbrate=$(awk -v tb=$diffvpn5txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + vpn5rxmbrate=0 + vpn5txmbrate=0 + fi + if [ "$wg1on" == "True" ] + then + wg1rxmbrate=$(awk -v rb=$diffwg1rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + wg1txmbrate=$(awk -v tb=$diffwg1txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + wg1rxmbrate=0 + wg1txmbrate=0 + fi + if [ "$wg2on" == "True" ] + then + wg2rxmbrate=$(awk -v rb=$diffwg2rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + wg2txmbrate=$(awk -v tb=$diffwg2txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + wg2rxmbrate=0 + wg2txmbrate=0 + fi + if [ "$wg3on" == "True" ] + then + wg3rxmbrate=$(awk -v rb=$diffwg3rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + wg3txmbrate=$(awk -v tb=$diffwg3txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + wg3rxmbrate=0 + wg3txmbrate=0 + fi + if [ "$wg4on" == "True" ] + then + wg4rxmbrate=$(awk -v rb=$diffwg4rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + wg4txmbrate=$(awk -v tb=$diffwg4txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + wg4rxmbrate=0 + wg4txmbrate=0 + fi + if [ "$wg5on" == "True" ] + then + wg5rxmbrate=$(awk -v rb=$diffwg5rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + wg5txmbrate=$(awk -v tb=$diffwg5txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + wg5rxmbrate=0 + wg5txmbrate=0 + fi + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ] + then + wanrxmbratedisplay=$(awk -v rb=$diffwanrxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + wantxmbratedisplay=$(awk -v tb=$diffwantxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + fi + + w24rxmbratedisplay=$(awk -v rb=$diff24rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + w24txmbratedisplay=$(awk -v tb=$diff24txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + w5rxmbratedisplay=$(awk -v rb=$diff5rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + w5txmbratedisplay=$(awk -v tb=$diff5txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + lanrxmbratedisplay=$(awk -v rb=$difflanrxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + lantxmbratedisplay=$(awk -v tb=$difflantxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ] + then + w52rxmbratedisplay=$(awk -v rb=$diff52rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + w52txmbratedisplay=$(awk -v tb=$diff52txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + else + w52rxmbratedisplay="" + w52txmbratedisplay="" + fi + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ] + then + w6rxmbratedisplay=$(awk -v rb=$diff6rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + w6txmbratedisplay=$(awk -v tb=$diff6txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + else + w6rxmbratedisplay="" + w6txmbratedisplay="" + fi + if [ "$FourBandCustom56624" == "True" ] + then + w62rxmbratedisplay=$(awk -v rb=$diff62rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + w62txmbratedisplay=$(awk -v tb=$diff62txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + else + w62rxmbratedisplay="" + w62txmbratedisplay="" + fi + if [ "$vpn1on" == "True" ] + then + vpnrxmbratedisplay=$(awk -v rb=$diffvpnrxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + vpntxmbratedisplay=$(awk -v tb=$diffvpntxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + else + vpnrxmbratedisplay="" + vpntxmbratedisplay="" + fi + if [ "$vpn2on" == "True" ] + then + vpn2rxmbratedisplay=$(awk -v rb=$diffvpn2rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + vpn2txmbratedisplay=$(awk -v tb=$diffvpn2txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + else + vpn2rxmbratedisplay="" + vpn2txmbratedisplay="" + fi + if [ "$vpn3on" == "True" ] + then + vpn3rxmbratedisplay=$(awk -v rb=$diffvpn3rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + vpn3txmbratedisplay=$(awk -v tb=$diffvpn3txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + else + vpn3rxmbratedisplay="" + vpn3txmbratedisplay="" + fi + if [ "$vpn4on" == "True" ] + then + vpn4rxmbratedisplay=$(awk -v rb=$diffvpn4rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + vpn4txmbratedisplay=$(awk -v tb=$diffvpn4txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + else + vpn4rxmbratedisplay="" + vpn4txmbratedisplay="" + fi + if [ "$vpn5on" == "True" ] + then + vpn5rxmbratedisplay=$(awk -v rb=$diffvpn5rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + vpn5txmbratedisplay=$(awk -v tb=$diffvpn5txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + else + vpn5rxmbratedisplay="" + vpn5txmbratedisplay="" + fi + if [ "$wg1on" == "True" ] + then + wg1rxmbratedisplay=$(awk -v rb=$diffwg1rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + wg1txmbratedisplay=$(awk -v tb=$diffwg1txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + else + wg1rxmbratedisplay="" + wg1txmbratedisplay="" + fi + if [ "$wg2on" == "True" ] + then + wg2rxmbratedisplay=$(awk -v rb=$diffwg2rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + wg2txmbratedisplay=$(awk -v tb=$diffwg2txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + else + wg2rxmbratedisplay="" + wg2txmbratedisplay="" + fi + if [ "$wg3on" == "True" ] + then + wg3rxmbratedisplay=$(awk -v rb=$diffwg3rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + wg3txmbratedisplay=$(awk -v tb=$diffwg3txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + else + wg3rxmbratedisplay="" + wg3txmbratedisplay="" + fi + if [ "$wg4on" == "True" ] + then + wg4rxmbratedisplay=$(awk -v rb=$diffwg4rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + wg4txmbratedisplay=$(awk -v tb=$diffwg4txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + else + wg4rxmbratedisplay="" + wg4txmbratedisplay="" + fi + if [ "$wg5on" == "True" ] + then + wg5rxmbratedisplay=$(awk -v rb=$diffwg5rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + wg5txmbratedisplay=$(awk -v tb=$diffwg5txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + else + wg5rxmbratedisplay="" + wg5txmbratedisplay="" + fi + + # Uptime calc # + uptimeStr="$(awk '{printf("%3dd %02dh %02dm %02ds\n",($1/60/60/24),($1/60/60%24),($1/60%60),($1%60))}' /proc/uptime)" + +} + +# ------------------------------------------------------------------------------------------------------------------------- + +# This function displays the stats UI for page 1 +DisplayPage1() +{ + + clear + if [ "$UpdateNotify" != "0" ]; then + echo -e "$UpdateNotify${CClear}" + fi + showheader + echo "" + echo -e "${InvDkGray}${CWhite} CPU ${CClear}" + echo "" + echo -e "${InvGreen} ${CClear} ${CWhite}Uptime ${CDkGray}[ ${CWhite}$uptimeStr${CDkGray} ]${CClear}" + echo -e "${InvGreen} ${CClear} ${CWhite}CPU Load ${CDkGray}[ ${CGreen}1m: ${CWhite}$cpuload1m ${CGreen}5m: ${CWhite}$cpuload5m ${CGreen}15m: ${CWhite}$cpuload15m${CDkGray} ]${CClear}" + preparebar 79 "|" + progressbar $oldcpuusr1 100 " CPU User " "%%" "Standard" $olddisplaycpuusr1 + echo "" + preparebar 79 "|" + progressbar $oldcpusys1 100 " CPU System" "%%" "Standard" $olddisplaycpusys1 + echo "" + preparebar 79 "|" + progressbar $oldcpunice1 100 " CPU Nice " "%%" "Standard" $olddisplaycpunice1 + echo "" + preparebar 79 "|" + progressbar $oldcpuidle1 100 " CPU Idle " "%%" "Reverse" $olddisplaycpuidle1 + echo "" + preparebar 79 "|" + progressbar $oldcpuirq1 100 " CPU IRQ " "%%" "Standard" $olddisplaycpuirq1 + echo "" + preparebar 79 "|" + converttemps $oldF_cputemp + progressbar $currenttemp $currentrange " CPU Temp " $TempUnits "CPU" $currenttemp $currentrange + echo "" + echo "" + echo -e "${InvDkGray}${CWhite} Memory ${CClear}" + echo "" + echo -en "${InvGreen} ${CClear} ${CWhite}Mem Total ${CDkGray}[ ${CWhite}" + printf "%-7s" "$totalphysmem MB" + echo -e "${CDkGray} ]${CClear}" + preparebar 79 "|" + progressbar $oldmemused2 $oldtotalmemory " Mem Used " "MB" "Standard" + echo "" + preparebar 79 "|" + progressbar $oldmemfree2 $oldtotalmemory " Mem Free " "MB" "Reverse" + echo "" + preparebar 79 "|" + progressbar $oldmemshrd2 $oldtotalmemory " Mem Shared" "MB" "Standard" + echo "" + preparebar 79 "|" + progressbar $oldmembuff2 $oldtotalmemory " Mem Buffer" "MB" "Standard" + echo "" + preparebar 79 "|" + progressbar $oldmemcach2 $oldtotalmemory " Mem Cache " "MB" "Standard" + echo "" + preparebar 79 "|" + progressbar $oldnvramused $oldtotalnvram " NVRAM Used" "B" "Standard" + echo "" + echo "" + echo -e "${InvDkGray}${CWhite} Disk ${CClear}" + echo "" + echo -en "${InvGreen} ${CClear} ${CWhite}Swap Size ${CDkGray}[ ${CWhite}" + printf "%-8s" "$swaptotal MB" + echo -e "${CDkGray} ]${CClear}" + preparebar 79 "|" + progressbar $oldswapused $oldswaptotal " Swap Used " "MB" "Standard" + echo "" + preparebar 79 "|" + progressbar $oldjffsused $oldjffstotal " JFFS Used " "MB" "Standard" + + #Disk - SD devices + if [ -s /jffs/addons/rtrmon.d/sdresult.txt ] + then + sdcnt=$(cat /jffs/addons/rtrmon.d/sdresult.txt | wc -l) >/dev/null 2>&1 + if [ -z "$sdcnt" ] || [ $sdcnt -lt 1 ]; then + sdcnt=0 + fi + else + sdcnt=0 + fi + + CNT=0 + while [ "$CNT" -lt "$sdcnt" ] # Loop through number of /dev/sd*'s # + do + CNT="$((CNT+1))" + dfresults="$(sed -n "${CNT}p" /jffs/addons/rtrmon.d/sdresult.txt)" + if [ -z "$dfresults" ]; then break; fi + sdname="$(echo $dfresults | awk '{print $1}')" + sdtotal="$(echo $dfresults | awk '{print $2}')" + sdused="$(echo $dfresults | awk '{print $3}')" + + sdtotal=$(echo "$sdtotal 1048576" | awk '{print $1/$2}' | cut -d . -f 1) + sdused=$(echo "$sdused 1048576" | awk '{print $1/$2}' | cut -d . -f 1) + if [ $sdtotal == "0" ]; then sdtotal=1; fi + if [ $sdused == "0" ]; then sdused=1; fi + sdnameformat=$(printf "%-10s" $sdname) + + echo "" + preparebar 79 "|" + progressbar $sdused $sdtotal " $sdnameformat" "GB" "Standard" + done +} + +# ------------------------------------------------------------------------------------------------------------------------- + +# This function displays the stats UI for page 2 +DisplayPage2() +{ + clear + if [ "$UpdateNotify" != "0" ]; then + echo -e "$UpdateNotify${CClear}" + fi + showheader + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + echo "" + echo -e "${InvDkGray}${CWhite} WAN ${CClear}" + echo "" + if [ "$ScreenshotMode" == "1" ]; then + oldwan0ip="1.2.3.4" #demo + oldwanip6="abc1:23de::f456:ghi7:89jk:l0mn:opqr" #demo + oldvpn1ip="2.3.4.5" #demo + oldvpn2ip="3.4.5.6" #demo + oldvpn3ip="4.5.6.7" #demo + oldvpn4ip="5.6.7.8" #demo + oldvpn5ip="6.7.8.9" #demo + oldwg1ip="2.3.4.5" #demo + oldwg2ip="3.4.5.6" #demo + oldwg3ip="4.5.6.7" #demo + oldwg4ip="5.6.7.8" #demo + oldwg5ip="6.7.8.9" #demo + oldvpn1city="Rivendell" #demo + oldvpn2city="Mordor" #demo + oldvpn3city="Minas Tirith" #demo + oldvpn4city="Edoras" #demo + oldvpn5city="Aglarond" #demo + oldwg1city="Rivendell" #demo + oldwg2city="Mordor" #demo + oldwg3city="Minas Tirith" #demo + oldwg4city="Edoras" #demo + oldwg5city="Aglarond" #demo + fi + echo -en "${InvGreen} ${CClear} ${CWhite}WAN 0/1 IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldwan0ip//./ } + echo -en " / " + printf '%03d.%03d.%03d.%03d' ${oldwan1ip//./ } + echo -en "${CDkGray} ] ${CWhite} DNS ${CDkGray}[ ${CWhite}" + if [ $olddns1ip = "0.0.0.0" ]; then printf "000.000.000.000"; else printf '%03d.%03d.%03d.%03d' ${olddns1ip//./ }; fi + echo -en " / " + if [ $olddns2ip = "0.0.0.0" ]; then printf "000.000.000.000"; else printf '%03d.%03d.%03d.%03d' ${olddns2ip//./ }; fi + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}IFace: $WANIFNAME${CClear}" + if [ ! -z $oldwanip6 ]; then echo -e "${InvGreen} ${CClear} ${CWhite}WAN 0/1 I6 ${CDkGray}[ ${CWhite}$oldwanip6${CClear}"; fi + preparebar 79 "|" + progressbar $oldwanrxmbrate $MaxSpeedInet " Avg WAN RX" "Mbps" "Standard" $oldwanrxmbratedisplay $MaxSpeedInet + echo "" + preparebar 79 "|" + progressbar $oldwantxmbrate $MaxSpeedInetUL " Avg WAN TX" "Mbps" "Standard" $oldwantxmbratedisplay $MaxSpeedInetUL + echo "" + fi + echo "" + echo -e "${InvDkGray}${CWhite} LAN ${CClear}" + echo "" + echo -en "${InvGreen} ${CClear}${CWhite} BR0 LAN IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldlanip//./ } + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}IFace: br0${CClear}" + if [ ! -z $oldlanip6 ]; then echo -e "${InvGreen} ${CClear} ${CWhite}BR0 LAN I6 ${CDkGray}[ ${CWhite}$oldlanip6${CClear}"; fi + + preparebar 79 "|" + progressbar $oldlanrxmbrate $MaxSpeedLAN " Avg LAN RX" "Mbps" "Standard" $oldlanrxmbratedisplay $MaxSpeedLAN + echo "" + preparebar 79 "|" + if [ ${oldlantxmbrate%.*} -lt 0 ]; then oldlantxmbrate=0; oldlantxmbratedisplay=0; fi + progressbar $oldlantxmbrate $MaxSpeedLAN " Avg LAN TX" "Mbps" "Standard" $oldlantxmbratedisplay $MaxSpeedLAN + + if [ "$vpn1on" == "True" ]; then + echo "" + echo "" + echo -e "${InvDkGray}${CWhite} OVPN$vpn1slot ${CClear}" + echo "" + if [ "$oldvpn1city" == "Private Network" ]; then + echo -en "${InvGreen} ${CClear}${CWhite} PRV VPN IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldvpn1ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldvpn1city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn1slot${CClear}" + else + echo -en "${InvGreen} ${CClear}${CWhite} PUB VPN IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldvpn1ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldvpn1city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn1slot${CClear}" + fi + if [ ${oldvpntxmbrate%.*} -lt 0 ]; then oldvpntxmbrate=0; oldvpntxmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldvpntxmbrate $MaxSpeedInet " Avg VPN RX" "Mbps" "Standard" $oldvpntxmbratedisplay $MaxSpeedInet + echo "" + if [ ${oldvpnrxmbrate%.*} -lt 0 ]; then oldvpnrxmbrate=0; oldvpnrxmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldvpnrxmbrate $MaxSpeedInetUL " Avg VPN TX" "Mbps" "Standard" $oldvpnrxmbratedisplay $MaxSpeedInetUL + fi + + if [ "$vpn2on" == "True" ]; then + echo "" + echo "" + echo -e "${InvDkGray}${CWhite} OVPN$vpn2slot ${CClear}" + echo "" + if [ "$oldvpn2city" == "Private Network" ]; then + echo -en "${InvGreen} ${CClear}${CWhite} PRV VPN IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldvpn2ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldvpn2city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn2slot${CClear}" + else + echo -en "${InvGreen} ${CClear}${CWhite} PUB VPN IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldvpn2ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldvpn2city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn2slot${CClear}" + fi + if [ ${oldvpn2txmbrate%.*} -lt 0 ]; then oldvpn2txmbrate=0; oldvpn2txmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldvpn2txmbrate $MaxSpeedInet " Avg VPN RX" "Mbps" "Standard" $oldvpn2txmbratedisplay $MaxSpeedInet + echo "" + if [ ${oldvpn2rxmbrate%.*} -lt 0 ]; then oldvpn2rxmbrate=0; oldvpn2rxmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldvpn2rxmbrate $MaxSpeedInetUL " Avg VPN TX" "Mbps" "Standard" $oldvpn2rxmbratedisplay $MaxSpeedInetUL + fi + + if [ "$vpn3on" == "True" ]; then + echo "" + echo "" + echo -e "${InvDkGray}${CWhite} OVPN$vpn3slot ${CClear}" + echo "" + if [ "$oldvpn3city" == "Private Network" ]; then + echo -en "${InvGreen} ${CClear}${CWhite} PRV VPN IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldvpn3ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldvpn3city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn3slot${CClear}" + else + echo -en "${InvGreen} ${CClear}${CWhite} PUB VPN IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldvpn3ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldvpn3city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn3slot${CClear}" + fi + if [ ${oldvpn3txmbrate%.*} -lt 0 ]; then oldvpn3txmbrate=0; oldvpn3txmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldvpn3txmbrate $MaxSpeedInet " Avg VPN RX" "Mbps" "Standard" $oldvpn3txmbratedisplay $MaxSpeedInet + echo "" + if [ ${oldvpn3rxmbrate%.*} -lt 0 ]; then oldvpn3rxmbrate=0; oldvpn3rxmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldvpn3rxmbrate $MaxSpeedInetUL " Avg VPN TX" "Mbps" "Standard" $oldvpn3rxmbratedisplay $MaxSpeedInetUL + fi + + if [ "$vpn4on" == "True" ]; then + echo "" + echo "" + echo -e "${InvDkGray}${CWhite} OVPN$vpn4slot ${CClear}" + echo "" + if [ "$oldvpn4city" == "Private Network" ]; then + echo -en "${InvGreen} ${CClear}${CWhite} PRV VPN IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldvpn4ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldvpn4city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn4slot${CClear}" + else + echo -en "${InvGreen} ${CClear}${CWhite} PUB VPN IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldvpn4ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldvpn4city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn4slot${CClear}" + fi + if [ ${oldvpn4txmbrate%.*} -lt 0 ]; then oldvpn4txmbrate=0; oldvpn4txmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldvpn4txmbrate $MaxSpeedInet " Avg VPN RX" "Mbps" "Standard" $oldvpn4txmbratedisplay $MaxSpeedInet + echo "" + if [ ${oldvpn4rxmbrate%.*} -lt 0 ]; then oldvpn4rxmbrate=0; oldvpn4rxmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldvpn4rxmbrate $MaxSpeedInetUL " Avg VPN TX" "Mbps" "Standard" $oldvpn4rxmbratedisplay $MaxSpeedInetUL + fi + + if [ "$vpn5on" == "True" ]; then + echo "" + echo "" + echo -e "${InvDkGray}${CWhite} OVPN$vpn5slot ${CClear}" + echo "" + if [ "$oldvpn5city" == "Private Network" ]; then + echo -en "${InvGreen} ${CClear}${CWhite} PRV VPN IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldvpn5ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldvpn5city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn5slot${CClear}" + else + echo -en "${InvGreen} ${CClear}${CWhite} PUB VPN IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldvpn5ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldvpn5city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn5slot${CClear}" + fi + if [ ${oldvpn5txmbrate%.*} -lt 0 ]; then oldvpn5txmbrate=0; oldvpn5txmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldvpn5txmbrate $MaxSpeedInet " Avg VPN RX" "Mbps" "Standard" $oldvpn5txmbratedisplay $MaxSpeedInet + echo "" + if [ ${oldvpn5rxmbrate%.*} -lt 0 ]; then oldvpn5rxmbrate=0; oldvpn5rxmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldvpn5rxmbrate $MaxSpeedInetUL " Avg VPN TX" "Mbps" "Standard" $oldvpn5rxmbratedisplay $MaxSpeedInetUL + fi + + if [ "$wg1on" == "True" ]; then + echo "" + echo "" + echo -e "${InvDkGray}${CWhite} WG$wg1slot ${CClear}" + echo "" + if [ "$oldwg1city" == "Private Network" ]; then + echo -en "${InvGreen} ${CClear}${CWhite} PRV WG IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldwg1ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldwg1city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg1slot${CClear}" + else + echo -en "${InvGreen} ${CClear}${CWhite} PUB WG IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldwg1ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldwg1city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg1slot${CClear}" + fi + if [ ${oldwg1txmbrate%.*} -lt 0 ]; then oldwg1txmbrate=0; oldwg1txmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldwg1txmbrate $MaxSpeedInet " Avg WG RX " "Mbps" "Standard" $oldwg1txmbratedisplay $MaxSpeedInet + echo "" + if [ ${oldwg1rxmbrate%.*} -lt 0 ]; then oldwg1rxmbrate=0; oldwg1rxmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldwg1rxmbrate $MaxSpeedInetUL " Avg WG TX " "Mbps" "Standard" $oldwg1rxmbratedisplay $MaxSpeedInetUL + fi + + if [ "$wg2on" == "True" ]; then + echo "" + echo "" + echo -e "${InvDkGray}${CWhite} WG$wg2slot ${CClear}" + echo "" + if [ "$oldwg2city" == "Private Network" ]; then + echo -en "${InvGreen} ${CClear}${CWhite} PRV WG IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldwg2ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldwg2city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg2slot${CClear}" + else + echo -en "${InvGreen} ${CClear}${CWhite} PUB WG IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldwg2ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldwg2city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg2slot${CClear}" + fi + if [ ${oldwg2txmbrate%.*} -lt 0 ]; then oldwg2txmbrate=0; oldwg2txmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldwg2txmbrate $MaxSpeedInet " Avg WG RX " "Mbps" "Standard" $oldwg2txmbratedisplay $MaxSpeedInet + echo "" + if [ ${oldwg2rxmbrate%.*} -lt 0 ]; then oldwg2rxmbrate=0; oldwg2rxmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldwg2rxmbrate $MaxSpeedInetUL " Avg WG TX " "Mbps" "Standard" $oldwg2rxmbratedisplay $MaxSpeedInetUL + fi + + if [ "$wg3on" == "True" ]; then + echo "" + echo "" + echo -e "${InvDkGray}${CWhite} WG$wg3slot ${CClear}" + echo "" + if [ "$oldwg3city" == "Private Network" ]; then + echo -en "${InvGreen} ${CClear}${CWhite} PRV WG IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldwg3ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldwg3city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg3slot${CClear}" + else + echo -en "${InvGreen} ${CClear}${CWhite} PUB WG IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldwg3ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldwg3city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg3slot${CClear}" + fi + if [ ${oldwg3txmbrate%.*} -lt 0 ]; then oldwg3txmbrate=0; oldwg3txmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldwg3txmbrate $MaxSpeedInet " Avg WG RX " "Mbps" "Standard" $oldwg3txmbratedisplay $MaxSpeedInet + echo "" + if [ ${oldwg3rxmbrate%.*} -lt 0 ]; then oldwg3rxmbrate=0; oldwg3rxmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldwg3rxmbrate $MaxSpeedInetUL " Avg WG TX " "Mbps" "Standard" $oldwg3rxmbratedisplay $MaxSpeedInetUL + fi + + if [ "$wg4on" == "True" ]; then + echo "" + echo "" + echo -e "${InvDkGray}${CWhite} WG$wg4slot ${CClear}" + echo "" + if [ "$oldwg4city" == "Private Network" ]; then + echo -en "${InvGreen} ${CClear}${CWhite} PRV WG IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldwg4ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldwg4city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg4slot${CClear}" + else + echo -en "${InvGreen} ${CClear}${CWhite} PUB WG IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldwg4ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldwg4city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg4slot${CClear}" + fi + if [ ${oldwg4txmbrate%.*} -lt 0 ]; then oldwg4txmbrate=0; oldwg4txmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldwg4txmbrate $MaxSpeedInet " Avg WG RX " "Mbps" "Standard" $oldwg4txmbratedisplay $MaxSpeedInet + echo "" + if [ ${oldwg4rxmbrate%.*} -lt 0 ]; then oldwg4rxmbrate=0; oldwg4rxmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldwg4rxmbrate $MaxSpeedInetUL " Avg WG TX " "Mbps" "Standard" $oldwg4rxmbratedisplay $MaxSpeedInetUL + fi + + if [ "$wg5on" == "True" ]; then + echo "" + echo "" + echo -e "${InvDkGray}${CWhite} WG$wg5slot ${CClear}" + echo "" + if [ "$oldwg5city" == "Private Network" ]; then + echo -en "${InvGreen} ${CClear}${CWhite} PRV WG IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldwg5ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldwg5city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg5slot${CClear}" + else + echo -en "${InvGreen} ${CClear}${CWhite} PUB WG IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldwg5ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldwg5city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg5slot${CClear}" + fi + if [ ${oldwg5txmbrate%.*} -lt 0 ]; then oldwg5txmbrate=0; oldwg5txmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldwg5txmbrate $MaxSpeedInet " Avg WG RX " "Mbps" "Standard" $oldwg5txmbratedisplay $MaxSpeedInet + echo "" + if [ ${oldwg5rxmbrate%.*} -lt 0 ]; then oldwg5rxmbrate=0; oldwg5rxmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldwg5rxmbrate $MaxSpeedInetUL " Avg WG TX " "Mbps" "Standard" $oldwg5rxmbratedisplay $MaxSpeedInetUL + fi + +} + +# ------------------------------------------------------------------------------------------------------------------------- + +# This function displays the stats UI for page 3 +DisplayPage3() +{ + clear + if [ "$UpdateNotify" != "0" ]; then + echo -e "$UpdateNotify${CClear}" + fi + showheader + # Per @Stephen Harrington's sugguestion, check NVRAM to see if Wifi is turned on, else mark them as disabled + if [ "$FourBandCustom55624" == "True" ]; then + if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then + MaxSpeed52GhzNow=0 + else + MaxSpeed52GhzNow=$MaxSpeed5Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then + MaxSpeed6GhzNow=0 + else + MaxSpeed6GhzNow=$MaxSpeed6Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl3_radio) -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + elif [ "$FourBandCustom56624" == "True" ]; then + if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then + MaxSpeed6GhzNow=0 + else + MaxSpeed6GhzNow=$MaxSpeed6Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then + MaxSpeed62GhzNow=0 + else + MaxSpeed62GhzNow=$MaxSpeed6Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl3_radio) -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + elif [ "$ThreeBand2456" == "True" ]; then + if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then + MaxSpeed6GhzNow=0 + else + MaxSpeed6GhzNow=$MaxSpeed6Ghz + fi + elif [ "$ThreeBand2455" == "True" ]; then + if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then + MaxSpeed52GhzNow=0 + else + MaxSpeed52GhzNow=$MaxSpeed5Ghz + fi + else + if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + fi + + echo "" + echo -e "${InvDkGray}${CWhite} WiFi ${CClear}" + echo "" + if [ "$MaxSpeed24GhzNow" != "0" ]; then + if [ "$w24updown" == "UP" ]; then + echo -e "${InvGreen} ${CClear} ${CWhite}2.4GHz ${CDkGray}[ ${CWhite}Enabled - $w24udsched - UP ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname24${CClear}" + else + echo -e "${InvGreen} ${CClear} ${CWhite}2.4GHz ${CDkGray}[ ${CWhite}Enabled - $w24udsched - DOWN ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname24${CClear}" + fi + preparebar 79 "|" + progressbar $oldw24rxmbrate $MaxSpeed24GhzNow " Avg 24G RX" "Mbps" "Standard" $oldw24rxmbratedisplay $MaxSpeed24GhzNow + echo "" + preparebar 79 "|" + progressbar $oldw24txmbrate $MaxSpeed24GhzNow " Avg 24G TX" "Mbps" "Standard" $oldw24txmbratedisplay $MaxSpeed24GhzNow + echo "" + preparebar 79 "|" + converttemps $oldw24temp + progressbar $currenttemp $currentrange " 2.4G Temp " $TempUnits "Standard" $currenttemp $currentrange + else + echo -e "${InvRed} ${CClear}${CWhite} 2.4GHz ${CDkGray}[ ${CRed}Disabled ${CDkGray}]${CClear}" + fi + if [ "$MaxSpeed5GhzNow" != "0" ]; then + echo "" + echo "" + if [ "$w5updown" == "UP" ]; then + echo -e "${InvGreen} ${CClear} ${CWhite}5.0GHz ${CDkGray}[ ${CWhite}Enabled - $w5udsched - UP ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname5${CClear}" + else + echo -e "${InvGreen} ${CClear} ${CWhite}5.0GHz ${CDkGray}[ ${CWhite}Enabled - $w5udsched - DOWN ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname5${CClear}" + fi + preparebar 79 "|" + progressbar $oldw5rxmbrate $MaxSpeed5GhzNow " Avg 5G1 RX" "Mbps" "Standard" $oldw5rxmbratedisplay $MaxSpeed5GhzNow + echo "" + preparebar 79 "|" + progressbar $oldw5txmbrate $MaxSpeed5GhzNow " Avg 5G1 TX" "Mbps" "Standard" $oldw5txmbratedisplay $MaxSpeed5GhzNow + echo "" + preparebar 79 "|" + converttemps $oldw5temp + progressbar $currenttemp $currentrange " 5G-1 Temp " $TempUnits "Standard" $currenttemp $currentrange + else + echo "" + echo "" + echo -e "${InvRed} ${CClear}${CWhite} 5.0GHz ${CDkGray}[ ${CRed}Disabled ${CDkGray}]${CClear}" + fi + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then + if [ "$MaxSpeed52GhzNow" != "0" ]; then + echo "" + echo "" + if [ "$w52updown" == "UP" ]; then + echo -e "${InvGreen} ${CClear} ${CWhite}5.0GHz (2) ${CDkGray}[ ${CWhite}Enabled - $w52udsched - UP ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname52${CClear}" + else + echo -e "${InvGreen} ${CClear} ${CWhite}5.0GHz (2) ${CDkGray}[ ${CWhite}Enabled - $w52udsched - DOWN ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname52${CClear}" + fi + preparebar 79 "|" + progressbar $oldw52rxmbrate $MaxSpeed5GhzNow " Avg 5G2 RX" "Mbps" "Standard" $oldw52rxmbratedisplay $MaxSpeed5GhzNow + echo "" + preparebar 79 "|" + progressbar $oldw52txmbrate $MaxSpeed5GhzNow " Avg 5G2 TX" "Mbps" "Standard" $oldw52txmbratedisplay $MaxSpeed5GhzNow + echo "" + preparebar 79 "|" + converttemps $oldw52temp + progressbar $currenttemp $currentrange " 5G-2 Temp " $TempUnits "Standard" $currenttemp $currentrange + else + echo "" + echo "" + echo -e "${InvRed} ${CClear}${CWhite} 5.0GHz (2) ${CDkGray}[ ${CRed}Disabled ${CDkGray}]${CClear}" + fi + fi + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then + if [ "$MaxSpeed6GhzNow" != "0" ]; then + echo "" + echo "" + if [ "$w6updown" == "UP" ]; then + echo -e "${InvGreen} ${CClear} ${CWhite}6.0GHz ${CDkGray}[ ${CWhite}Enabled - $w6udsched - UP ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname6${CClear}" + else + echo -e "${InvGreen} ${CClear} ${CWhite}6.0GHz ${CDkGray}[ ${CWhite}Enabled - $w6udsched - DOWN ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname6${CClear}" + fi + preparebar 79 "|" + progressbar $oldw6rxmbrate $MaxSpeed6GhzNow " Avg 60G RX" "Mbps" "Standard" $oldw6rxmbratedisplay $MaxSpeed6GhzNow + echo "" + preparebar 79 "|" + progressbar $oldw6txmbrate $MaxSpeed6GhzNow " Avg 60G TX" "Mbps" "Standard" $oldw6txmbratedisplay $MaxSpeed6GhzNow + echo "" + preparebar 79 "|" + converttemps $oldw6temp + progressbar $currenttemp $currentrange " 6.0G Temp " $TempUnits "Standard" $currenttemp $currentrange + else + echo "" + echo "" + echo -e "${InvRed} ${CClear}${CWhite} 6.0GHz ${CDkGray}[ ${CRed}Disabled ${CDkGray}]${CClear}" + fi + fi + if [ "$FourBandCustom56624" == "True" ]; then + if [ "$MaxSpeed62GhzNow" != "0" ]; then + echo "" + echo "" + if [ "$w62updown" == "UP" ]; then + echo -e "${InvGreen} ${CClear} ${CWhite}6.0GHz (2) ${CDkGray}[ ${CWhite}Enabled - $w62udsched - UP ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname62${CClear}" + else + echo -e "${InvGreen} ${CClear} ${CWhite}6.0GHz (2) ${CDkGray}[ ${CWhite}Enabled - $w62udsched - DOWN ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname62${CClear}" + fi + preparebar 79 "|" + progressbar $oldw62rxmbrate $MaxSpeed62GhzNow " Avg 6G2 RX" "Mbps" "Standard" $oldw62rxmbratedisplay $MaxSpeed62GhzNow + echo "" + preparebar 79 "|" + progressbar $oldw62txmbrate $MaxSpeed62GhzNow " Avg 6G2 TX" "Mbps" "Standard" $oldw62txmbratedisplay $MaxSpeed62GhzNow + echo "" + preparebar 79 "|" + converttemps $oldw62temp + progressbar $currenttemp $currentrange " 6G-2 Temp " $TempUnits "Standard" $currenttemp $currentrange + else + echo "" + echo "" + echo -e "${InvRed} ${CClear}${CWhite} 6.0GHz (2) ${CDkGray}[ ${CRed}Disabled ${CDkGray}]${CClear}" + fi + fi +} + +# ------------------------------------------------------------------------------------------------------------------------- + +# This function displays the stats UI for page 4 +DisplayPage4() +{ + clear + if [ "$UpdateNotify" != "0" ]; then + echo -e "$UpdateNotify${CClear}" + fi + showheader + echo "" + echo -e "${InvDkGray}${CWhite} Speedtest ${CClear}" + + if [ "$QueueVPNSlot1" = "1" ]; then + DisplaySpdtst 1 + elif [ "$QueueVPNSlot2" = "1" ]; then + DisplaySpdtst 2 + elif [ "$QueueVPNSlot3" = "1" ]; then + DisplaySpdtst 3 + elif [ "$QueueVPNSlot4" = "1" ]; then + DisplaySpdtst 4 + elif [ "$QueueVPNSlot5" = "1" ]; then + DisplaySpdtst 5 + elif [ "$QueueWGSlot1" = "1" ]; then + DisplaySpdtst 6 + elif [ "$QueueWGSlot2" = "1" ]; then + DisplaySpdtst 7 + elif [ "$QueueWGSlot3" = "1" ]; then + DisplaySpdtst 8 + elif [ "$QueueWGSlot4" = "1" ]; then + DisplaySpdtst 9 + elif [ "$QueueWGSlot5" = "1" ]; then + DisplaySpdtst 0 + else + DisplaySpdtst + fi +} + +# ------------------------------------------------------------------------------------------------------------------------- + +# This function displays speedtest results and runs new speedtest +# $1 = VPN Slot + +DisplaySpdtst() +{ + if [ "$Speedtst" = "0" ] || [ ! -f $OOKLAPATH ]; then + echo -e "${InvGreen} ${CClear}" + echo -e "${InvRed} ${CClear} ${CRed}[Ookla Speedtest is not installed/configured]${CClear}" + sleep 3 + return + fi + + # Check to see if previous results are available to display + if [ -f "$SPDRESPATH" ]; then + source "$SPDRESPATH" + else + SpdDate="No previous results found" + SpdServer="Press 'I' to Initiate a Speedtest" + SpdLatency=0 + SpdJitter=0 + SpdPacketLoss=0 + SpdDownload=0 + SpdUpload=0 + fi + + echo -e "${InvGreen} ${CClear}" + + if [ "$QueueSpdTest" = "1" ] + then + #run speedtest and save Results + printf "\r${InvGreen} ${CClear} ${CGreen}[Initializing WAN Speedtest]" + #printf "${CGreen}\r[Initializing WAN Speedtest]" + if [ $spdtestsvrID == "0" ]; then + speed="$(/jffs/addons/rtrmon.d/speedtest --format=csv --interface=$WANIFNAME --accept-license --accept-gdpr 2>&1)" + else + speed="$(/jffs/addons/rtrmon.d/speedtest --format=csv --interface=$WANIFNAME --server-id=$spdtestsvrID --accept-license --accept-gdpr 2>&1)" + fi + SpdDate=$(date) + SpdServer=$(echo $speed | awk -F '","' 'NR==1 {print $1}' | sed -e 's/^"//' -e 's/"$//' -e 's/[^a-zA-Z0-9 -]//g') + SpdLatency=$(echo $speed | awk -F '","' 'NR==1 {print $3}' | sed -e 's/^"//' -e 's/"$//') + SpdLatencyLo=$(echo $speed | awk -F '","' 'NR==1 {print $20}' | sed -e 's/^"//' -e 's/"$//') + SpdLatencyHi=$(echo $speed | awk -F '","' 'NR==1 {print $21}' | sed -e 's/^"//' -e 's/"$//') + SpdJitter=$(echo $speed | awk -F '","' 'NR==1 {print $4}' | sed -e 's/^"//' -e 's/"$//') + SpdPacketLoss=$(echo $speed | awk -F '","' 'NR==1 {print $5}' | sed -e 's/^"//' -e 's/"$//') + SpdDownload=$(echo $speed | awk -F '","' 'NR==1 {print $6}' | sed -e 's/^"//' -e 's/"$//') + SpdUpload=$(echo $speed | awk -F '","' 'NR==1 {print $7}' | sed -e 's/^"//' -e 's/"$//') + SpdDLLatency=$(echo $speed | awk -F '","' 'NR==1 {print $12}' | sed -e 's/^"//' -e 's/"$//') + SpdDLLatencyJt=$(echo $speed | awk -F '","' 'NR==1 {print $13}' | sed -e 's/^"//' -e 's/"$//') + SpdDLLatencyLo=$(echo $speed | awk -F '","' 'NR==1 {print $14}' | sed -e 's/^"//' -e 's/"$//') + SpdDLLatencyHi=$(echo $speed | awk -F '","' 'NR==1 {print $15}' | sed -e 's/^"//' -e 's/"$//') + SpdULLatency=$(echo $speed | awk -F '","' 'NR==1 {print $16}' | sed -e 's/^"//' -e 's/"$//') + SpdULLatencyJt=$(echo $speed | awk -F '","' 'NR==1 {print $17}' | sed -e 's/^"//' -e 's/"$//') + SpdULLatencyLo=$(echo $speed | awk -F '","' 'NR==1 {print $18}' | sed -e 's/^"//' -e 's/"$//') + SpdULLatencyHi=$(echo $speed | awk -F '","' 'NR==1 {print $19}' | sed -e 's/^"//' -e 's/"$//') + + if [ $SpdDownload -eq 0 ]; then SpdDownload=1; fi + if [ $SpdUpload -eq 0 ]; then SpdUpload=1; fi + + SpdDownloadLog=$(awk -v down=$SpdDownload -v mb=125000 'BEGIN{printf "%.0f\n", down/mb}') + SpdUploadLog=$(awk -v up=$SpdUpload -v mb=125000 'BEGIN{printf "%.0f\n", up/mb}') + SpdInterface=$WANIFNAME + + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - New Speedtest Results -- Down:$SpdDownloadLog Mbps | Up:$SpdUploadLog Mbps | Latency:$SpdLatency ms | Jitter:$SpdJitter ms | PacketLoss:$SpdPacketLoss %" >> $LOGFILE + + { echo 'SpdDate="'"$SpdDate"'"' + echo 'SpdServer="'"$SpdServer"'"' + echo 'SpdInterface="'"$SpdInterface"'"' + echo 'SpdLatency='$SpdLatency + echo 'SpdLatencyLo='$SpdLatencyLo + echo 'SpdLatencyHi='$SpdLatencyHi + echo 'SpdJitter='$SpdJitter + echo 'SpdPacketLoss='$SpdPacketLoss + echo 'SpdDownload='$SpdDownload + echo 'SpdUpload='$SpdUpload + echo 'SpdDLLatency='$SpdDLLatency + echo 'SpdDLLatencyJt='$SpdDLLatencyJt + echo 'SpdDLLatencyLo='$SpdDLLatencyLo + echo 'SpdDLLatencyHi='$SpdDLLatencyHi + echo 'SpdULLatency='$SpdULLatency + echo 'SpdULLatencyJt='$SpdULLatencyJt + echo 'SpdULLatencyLo='$SpdULLatencyLo + echo 'SpdULLatencyHi='$SpdULLatencyHi + } > "$SPDRESPATH" + printf "${CGreen}\r" + QueueSpdTest=0 + fi + + if [ "$1" = "1" ] || [ "$1" = "2" ] || [ "$1" = "3" ] || [ "$1" = "4" ] || [ "$1" = "5" ] + then + #run VPN speedtest and save Results + selectedvpnslot="vpn${1}on" + eval selectedvpnslot="\$${selectedvpnslot}" + if [ "$selectedvpnslot" = "True" ] && [ "$VPNSite2Site" = "0" ] + then + printf "\r${InvGreen} ${CClear} ${CGreen}[Initializing VPN$1 Speedtest]" + if [ $spdtestsvrID == "0" ]; then + speed="$(/jffs/addons/rtrmon.d/speedtest --format=csv --interface=tun1$1 --accept-license --accept-gdpr 2>&1)" + else + speed="$(/jffs/addons/rtrmon.d/speedtest --format=csv --interface=tun1$1 --server-id=$spdtestsvrID --accept-license --accept-gdpr 2>&1)" + fi + SpdDate=$(date) + SpdServer=$(echo $speed | awk -F '","' 'NR==1 {print $1}' | sed -e 's/^"//' -e 's/"$//' -e 's/[^a-zA-Z0-9 -]//g') + SpdLatency=$(echo $speed | awk -F '","' 'NR==1 {print $3}' | sed -e 's/^"//' -e 's/"$//') + SpdLatencyLo=$(echo $speed | awk -F '","' 'NR==1 {print $20}' | sed -e 's/^"//' -e 's/"$//') + SpdLatencyHi=$(echo $speed | awk -F '","' 'NR==1 {print $21}' | sed -e 's/^"//' -e 's/"$//') + SpdJitter=$(echo $speed | awk -F '","' 'NR==1 {print $4}' | sed -e 's/^"//' -e 's/"$//') + SpdPacketLoss=$(echo $speed | awk -F '","' 'NR==1 {print $5}' | sed -e 's/^"//' -e 's/"$//') + SpdDownload=$(echo $speed | awk -F '","' 'NR==1 {print $6}' | sed -e 's/^"//' -e 's/"$//') + SpdUpload=$(echo $speed | awk -F '","' 'NR==1 {print $7}' | sed -e 's/^"//' -e 's/"$//') + SpdDLLatency=$(echo $speed | awk -F '","' 'NR==1 {print $12}' | sed -e 's/^"//' -e 's/"$//') + SpdDLLatencyJt=$(echo $speed | awk -F '","' 'NR==1 {print $13}' | sed -e 's/^"//' -e 's/"$//') + SpdDLLatencyLo=$(echo $speed | awk -F '","' 'NR==1 {print $14}' | sed -e 's/^"//' -e 's/"$//') + SpdDLLatencyHi=$(echo $speed | awk -F '","' 'NR==1 {print $15}' | sed -e 's/^"//' -e 's/"$//') + SpdULLatency=$(echo $speed | awk -F '","' 'NR==1 {print $16}' | sed -e 's/^"//' -e 's/"$//') + SpdULLatencyJt=$(echo $speed | awk -F '","' 'NR==1 {print $17}' | sed -e 's/^"//' -e 's/"$//') + SpdULLatencyLo=$(echo $speed | awk -F '","' 'NR==1 {print $18}' | sed -e 's/^"//' -e 's/"$//') + SpdULLatencyHi=$(echo $speed | awk -F '","' 'NR==1 {print $19}' | sed -e 's/^"//' -e 's/"$//') + + if [ $SpdDownload -eq 0 ]; then SpdDownload=1; fi + if [ $SpdUpload -eq 0 ]; then SpdUpload=1; fi + + SpdDownloadLog=$(awk -v down=$SpdDownload -v mb=125000 'BEGIN{printf "%.0f\n", down/mb}') + SpdUploadLog=$(awk -v up=$SpdUpload -v mb=125000 'BEGIN{printf "%.0f\n", up/mb}') + SpdInterface="tun1$1" + + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - New VPN$1 Speedtest Results -- Down:$SpdDownloadLog Mbps | Up:$SpdUploadLog Mbps | Latency:$SpdLatency ms | Jitter:$SpdJitter ms | PacketLoss:$SpdPacketLoss %" >> $LOGFILE + + { echo 'SpdDate="'"$SpdDate"'"' + echo 'SpdServer="'"$SpdServer"'"' + echo 'SpdInterface="'"$SpdInterface"'"' + echo 'SpdLatency='$SpdLatency + echo 'SpdLatencyLo='$SpdLatencyLo + echo 'SpdLatencyHi='$SpdLatencyHi + echo 'SpdJitter='$SpdJitter + echo 'SpdPacketLoss='$SpdPacketLoss + echo 'SpdDownload='$SpdDownload + echo 'SpdUpload='$SpdUpload + echo 'SpdDLLatency='$SpdDLLatency + echo 'SpdDLLatencyJt='$SpdDLLatencyJt + echo 'SpdDLLatencyLo='$SpdDLLatencyLo + echo 'SpdDLLatencyHi='$SpdDLLatencyHi + echo 'SpdULLatency='$SpdULLatency + echo 'SpdULLatencyJt='$SpdULLatencyJt + echo 'SpdULLatencyLo='$SpdULLatencyLo + echo 'SpdULLatencyHi='$SpdULLatencyHi + } > $SPDRESPATH + printf "\r${CClear}" + QueueVPNSlot1=0 + QueueVPNSlot2=0 + QueueVPNSlot3=0 + QueueVPNSlot4=0 + QueueVPNSlot5=0 + else + printf "\r${InvRed} ${CClear}${CRed} [No valid VPN tunnel detected to run Speedtest on]${CClear}" + sleep 3 + printf "\r${CClear} " + QueueVPNSlot1=0 + QueueVPNSlot2=0 + QueueVPNSlot3=0 + QueueVPNSlot4=0 + QueueVPNSlot5=0 + fi + fi + + if [ "$1" = "0" ] || [ "$1" = "6" ] || [ "$1" = "7" ] || [ "$1" = "8" ] || [ "$1" = "9" ] + then + if [ $1 -eq 6 ]; then selectedslotnum=1 + elif [ $1 -eq 7 ]; then selectedslotnum=2 + elif [ $1 -eq 8 ]; then selectedslotnum=3 + elif [ $1 -eq 9 ]; then selectedslotnum=4 + elif [ $1 -eq 0 ]; then selectedslotnum=5 + fi + #run WG speedtest and save Results + selectedwgslot="wg${selectedslotnum}on" + eval selectedwgslot="\$${selectedwgslot}" + if [ "$selectedwgslot" = "True" ] && [ "$VPNSite2Site" = "0" ] + then + + SPDWGTUN="wgc$selectedslotnum" + SPDNVRAMWGSLOTADDR=$($timeoutcmd$timeoutsec nvram get "$SPDWGTUN"_addr | cut -d '/' -f1) + + # Added based on suggestion from @ZebMcKayhan + ip rule add from $SPDNVRAMWGSLOTADDR lookup $SPDWGTUN prio 10 >/dev/null 2>&1 + ip -6 rule add from all oif $SPDWGTUN lookup $SPDWGTUN prio 10 >/dev/null 2>&1 #Mod to handle IPv6 + + printf "\r${InvGreen} ${CClear} ${CGreen}[Initializing WG${selectedslotnum} Speedtest]" + + if [ $spdtestsvrID == "0" ]; then + speed="$(/jffs/addons/rtrmon.d/speedtest --format=csv --interface=wgc${selectedslotnum} --accept-license --accept-gdpr 2>&1)" + else + speed="$(/jffs/addons/rtrmon.d/speedtest --format=csv --interface=wgc${selectedslotnum} --server-id=$spdtestsvrID --accept-license --accept-gdpr 2>&1)" + fi + + # Added based on suggestion from @ZebMcKayhan + ip rule del prio 10 >/dev/null 2>&1 + ip -6 rule del prio 10 >/dev/null 2>&1 + + # Clean up any garbage data per @ZebMcKayhan + speed=$(echo $speed | sed 's/^[^"]*//') + + SpdDate=$(date) + SpdServer=$(echo $speed | awk -F '","' 'NR==1 {print $1}' | sed -e 's/^"//' -e 's/"$//' -e 's/[^a-zA-Z0-9 -]//g') + SpdLatency=$(echo $speed | awk -F '","' 'NR==1 {print $3}' | sed -e 's/^"//' -e 's/"$//') + SpdLatencyLo=$(echo $speed | awk -F '","' 'NR==1 {print $20}' | sed -e 's/^"//' -e 's/"$//') + SpdLatencyHi=$(echo $speed | awk -F '","' 'NR==1 {print $21}' | sed -e 's/^"//' -e 's/"$//') + SpdJitter=$(echo $speed | awk -F '","' 'NR==1 {print $4}' | sed -e 's/^"//' -e 's/"$//') + SpdPacketLoss=$(echo $speed | awk -F '","' 'NR==1 {print $5}' | sed -e 's/^"//' -e 's/"$//') + SpdDownload=$(echo $speed | awk -F '","' 'NR==1 {print $6}' | sed -e 's/^"//' -e 's/"$//') + SpdUpload=$(echo $speed | awk -F '","' 'NR==1 {print $7}' | sed -e 's/^"//' -e 's/"$//') + SpdDLLatency=$(echo $speed | awk -F '","' 'NR==1 {print $12}' | sed -e 's/^"//' -e 's/"$//') + SpdDLLatencyJt=$(echo $speed | awk -F '","' 'NR==1 {print $13}' | sed -e 's/^"//' -e 's/"$//') + SpdDLLatencyLo=$(echo $speed | awk -F '","' 'NR==1 {print $14}' | sed -e 's/^"//' -e 's/"$//') + SpdDLLatencyHi=$(echo $speed | awk -F '","' 'NR==1 {print $15}' | sed -e 's/^"//' -e 's/"$//') + SpdULLatency=$(echo $speed | awk -F '","' 'NR==1 {print $16}' | sed -e 's/^"//' -e 's/"$//') + SpdULLatencyJt=$(echo $speed | awk -F '","' 'NR==1 {print $17}' | sed -e 's/^"//' -e 's/"$//') + SpdULLatencyLo=$(echo $speed | awk -F '","' 'NR==1 {print $18}' | sed -e 's/^"//' -e 's/"$//') + SpdULLatencyHi=$(echo $speed | awk -F '","' 'NR==1 {print $19}' | sed -e 's/^"//' -e 's/"$//') + + if [ $SpdDownload -eq 0 ]; then SpdDownload=1; fi + if [ $SpdUpload -eq 0 ]; then SpdUpload=1; fi + + SpdDownloadLog=$(awk -v down=$SpdDownload -v mb=125000 'BEGIN{printf "%.0f\n", down/mb}') + SpdUploadLog=$(awk -v up=$SpdUpload -v mb=125000 'BEGIN{printf "%.0f\n", up/mb}') + SpdInterface="wgc${selectedslotnum}" + + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - New WG${selectedslotnum} Speedtest Results -- Down:$SpdDownloadLog Mbps | Up:$SpdUploadLog Mbps | Latency:$SpdLatency ms | Jitter:$SpdJitter ms | PacketLoss:$SpdPacketLoss %" >> $LOGFILE + + { echo 'SpdDate="'"$SpdDate"'"' + echo 'SpdServer="'"$SpdServer"'"' + echo 'SpdInterface="'"$SpdInterface"'"' + echo 'SpdLatency='$SpdLatency + echo 'SpdLatencyLo='$SpdLatencyLo + echo 'SpdLatencyHi='$SpdLatencyHi + echo 'SpdJitter='$SpdJitter + echo 'SpdPacketLoss='$SpdPacketLoss + echo 'SpdDownload='$SpdDownload + echo 'SpdUpload='$SpdUpload + echo 'SpdDLLatency='$SpdDLLatency + echo 'SpdDLLatencyJt='$SpdDLLatencyJt + echo 'SpdDLLatencyLo='$SpdDLLatencyLo + echo 'SpdDLLatencyHi='$SpdDLLatencyHi + echo 'SpdULLatency='$SpdULLatency + echo 'SpdULLatencyJt='$SpdULLatencyJt + echo 'SpdULLatencyLo='$SpdULLatencyLo + echo 'SpdULLatencyHi='$SpdULLatencyHi + } > $SPDRESPATH + printf "\r${CClear}" + QueueWGSlot1=0 + QueueWGSlot2=0 + QueueWGSlot3=0 + QueueWGSlot4=0 + QueueWGSlot5=0 + else + printf "\r${InvRed} ${CClear}${CRed} [No valid WG tunnel detected to run Speedtest on]${CClear}" + sleep 3 + printf "\r${CClear} " + QueueWGSlot1=0 + QueueWGSlot2=0 + QueueWGSlot3=0 + QueueWGSlot4=0 + QueueWGSlot5=0 + fi + fi + + # Display previous results + if [ $SpdDownload -eq 0 ] || [ -z $SpdDownload ]; then SpdDownload=1; fi + if [ $SpdUpload -eq 0 ] || [ -z $SpdUpload ]; then SpdUpload=1; fi + + SpdDownload=$(awk -v down=$SpdDownload -v mb=125000 'BEGIN{printf "%.0f\n", down/mb}') + SpdUpload=$(awk -v up=$SpdUpload -v mb=125000 'BEGIN{printf "%.0f\n", up/mb}') + + if [ "$ScreenshotMode" == "1" ]; then + SpdServer="Starlink Satellite Transceiver #488028" + fi + + if { [ "$vpn1on" = "True" ] || [ "$vpn2on" = "True" ] || [ "$vpn3on" = "True" ] || [ "$vpn4on" = "True" ] || [ "$vpn5on" = "True" ]; } && { [ "$wg1on" = "True" ] || [ "$wg2on" = "True" ] || [ "$wg3on" = "True" ] || [ "$wg4on" = "True" ] || [ "$wg5on" = "True" ]; }; then + printf "\r${InvGreen} ${CClear} ${CGreen}(I)${CWhite}nitiate WAN Speedtest on: ${CGreen}$WANIFNAME ${CWhite}| VPN 1:${CGreen}(1) ${CWhite}2:${CGreen}(2) ${CWhite}3:${CGreen}(3) ${CWhite}4:${CGreen}(4) ${CWhite}5:${CGreen}(5) ${CWhite} | WG 1:${CGreen}(6) ${CWhite}2:${CGreen}(7) ${CWhite}3:${CGreen}(8) ${CWhite}4:${CGreen}(9) ${CWhite}5:${CGreen}(0)${CClear}" + elif [ "$vpn1on" = "True" ] || [ "$vpn2on" = "True" ] || [ "$vpn3on" = "True" ] || [ "$vpn4on" = "True" ] || [ "$vpn5on" = "True" ]; then + printf "\r${InvGreen} ${CClear} ${CGreen}(I)${CWhite}nitiate WAN Speedtest on: ${CGreen}$WANIFNAME ${CWhite}| VPN 1:${CGreen}(1) ${CWhite}2:${CGreen}(2) ${CWhite}3:${CGreen}(3) ${CWhite}4:${CGreen}(4) ${CWhite}5:${CGreen}(5) ${CWhite} | ${CDkGray}WG 1:(6) 2:(7) 3:(8) 4:(9) 5:(0)${CClear}" + elif [ "$wg1on" = "True" ] || [ "$wg2on" = "True" ] || [ "$wg3on" = "True" ] || [ "$wg4on" = "True" ] || [ "$wg5on" = "True" ]; then + printf "\r${InvGreen} ${CClear} ${CGreen}(I)${CWhite}nitiate WAN Speedtest on: ${CGreen}$WANIFNAME ${CWhite}| ${CDkGray}VPN 1:(1) 2:(2) 3:(3) 4:(4) 5:(5) ${CWhite} | WG 1:${CGreen}(6) ${CWhite}2:${CGreen}(7) ${CWhite}3:${CGreen}(8) ${CWhite}4:${CGreen}(9) ${CWhite}5:${CGreen}(0)${CClear}" + else + printf "\r${InvGreen} ${CClear} ${CGreen}(I)${CWhite}nitiate WAN Speedtest${CClear} " + fi + + echo "" + echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${InvGreen} ${CClear} ${CWhite}Test Date ${CDkGray}[ ${CGreen}$SpdDate${CClear}" + echo -e "${InvGreen} ${CClear} ${CWhite}Server ${CDkGray}[ ${CGreen}$SpdServer${CClear}" + echo -e "${InvGreen} ${CClear} ${CWhite}Interface ${CDkGray}[ ${CGreen}$SpdInterface${CClear}" + echo "" + echo -e "${InvGreen} ${CClear} ${CWhite}Idle Latency ${CDkGray}[ ${CGreen}$SpdLatency (ms)${CWhite} | Latency Low: ${CGreen}$SpdLatencyLo (ms) ${CWhite}| High: ${CGreen}$SpdLatencyHi (ms)${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} ${CWhite}Idle Jitter ${CDkGray}[ ${CGreen}$SpdJitter (ms)${CClear}" + echo -e "${InvGreen} ${CClear} ${CWhite}PacketLoss ${CDkGray}[ ${CGreen}$SpdPacketLoss (%)${CClear}" + echo "" + echo -e "${InvGreen} ${CClear} ${CWhite}Download ${CDkGray}[ ${CGreen}$SpdDownload (Mbps)${CWhite} | Jitter: ${CGreen}$SpdDLLatencyJt (ms)${CClear}" + echo -e "${InvGreen} ${CClear} ${CDkGray} [ ${CWhite}Latency: ${CGreen}$SpdDLLatency (ms)${CWhite} | Latency Low: ${CGreen}$SpdDLLatencyLo (ms) ${CWhite}| High: ${CGreen}$SpdDLLatencyHi (ms)${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} ${CCyan}Upload ${CDkGray}[ ${CGreen}$SpdUpload (Mbps)${CWhite} | Jitter: ${CGreen}$SpdULLatencyJt (ms)${CClear}" + echo -e "${InvGreen} ${CClear} ${CDkGray} [ ${CWhite}Latency: ${CGreen}$SpdULLatency (ms)${CWhite} | Latency Low: ${CGreen}$SpdULLatencyLo (ms) ${CWhite}| High: ${CGreen}$SpdULLatencyHi (ms)${CClear}" + echo "" + preparebar 79 "|" + progressbar $SpdDownload $MaxSpeedInet " DL vs WAN " "Mbps" "Reverse" $SpdDownload $MaxSpeedInet + echo "" + preparebar 79 "|" + progressbar $SpdUpload $MaxSpeedInetUL " UL vs WAN " "Mbps" "Reverse" $SpdUpload $MaxSpeedInetUL +} + +# ------------------------------------------------------------------------------------------------------------------------- + +# This function displays the stats UI for page 5 which includes network diagnostics and open port scanning +DisplayPage5() +{ + local ALIVE + local YEAR + local NW_STATE + local RES_STATE + local HOST_STATE + local CURL_STATE + local SPIDER_STATE + local SSL_STATE + #oldwan0ip="123.45.67.89" + + # Check to see if previous results are available to display + if [ -f "$DIAGRESPATH" ]; then + source "$DIAGRESPATH" + else + Lastruntime="No previous results found" + LocalClockTest="Failed" + NetworkConnTest="Failed" + NetworkResTest="Failed" + DigFuncTest="Failed" + CurlFuncTest="Failed" + SpiderFuncTest="Failed" + SSLHandshakeTest="Failed" + fi + + clear + if [ "$UpdateNotify" != "0" ]; then + echo -e "$UpdateNotify${CClear}" + fi + showheader + echo "" + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} Network Diagnostics ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} ${CWhite}Run ${CGreen}(D)${CWhite}iagnostics | Last Run Date/Time: ${CGreen}$Lastruntime" + echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo "" + + if [ "$QueueNetworkDiag" = "1" ] + then + #run network diags and save Results + printf "${InvYellow} ${CClear} ${CWhite}Local Clock Test... ${CYellow}[Checking] ${CDkGray}| date > 1970${CClear}" + YEAR="$(/bin/date +"%Y")" + sleep 1 + if [ "$YEAR" -gt 1970 ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Local Clock Test... ${CGreen}[Passed] ${CDkGray}| date > 1970${CClear}" + LocalClockTest="Passed" + else + printf "\r${InvRed} ${CClear} ${CWhite}Local Clock Test... ${CRed}[Failed] ${CDkGray}| date > 1970${CClear}" + LocalClockTest="Failed" + fi + echo "" + printf "${InvYellow} ${CClear} ${CWhite}Network Connectivity Test... ${CYellow}[Checking] ${CDkGray}| ping 1.1.1.1 -c1 -W2${CClear}" + NW_STATE="$(ping 1.1.1.1 -c1 -W2 >/dev/null 2>&1; echo $?)" + sleep 1 + if [ "$NW_STATE" = "0" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Network Connectivity Test... ${CGreen}[Passed] ${CDkGray}| ping 1.1.1.1 -c1 -W2${CClear}" + NetworkConnTest="Passed" + else + printf "\r${InvRed} ${CClear} ${CWhite}Network Connectivity Test... ${CRed}[Failed] ${CDkGray}| ping 1.1.1.1 -c1 -W2${CClear}" + NetworkConnTest="Failed" + fi + echo "" + + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + printf "${InvYellow} ${CClear} ${CWhite}Network Resolution Test... ${CYellow}[Checking] ${CDkGray}| nslookup google.com 127.0.0.1${CClear}" + RES_STATE="$(nslookup google.com 127.0.0.1 >/dev/null 2>&1; echo $?)" + sleep 1 + if [ "$RES_STATE" = "0" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Network Resolution Test... ${CGreen}[Passed] ${CDkGray}| nslookup google.com 127.0.0.1${CClear}" + NetworkResTest="Passed" + else + printf "\r${InvRed} ${CClear} ${CWhite}Network Resolution Test... ${CRed}[Failed] ${CDkGray}| nslookup google.com 127.0.0.1${CClear}" + NetworkResTest="Failed" + fi + echo "" + else + printf "${InvYellow} ${CClear} ${CWhite}Network Resolution Test... ${CYellow}[Checking] ${CDkGray}| nslookup google.com${CClear}" + RES_STATE="$(nslookup google.com >/dev/null 2>&1; echo $?)" + sleep 1 + if [ "$RES_STATE" = "0" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Network Resolution Test... ${CGreen}[Passed] ${CDkGray}| nslookup google.com${CClear}" + NetworkResTest="Passed" + else + printf "\r${InvRed} ${CClear} ${CWhite}Network Resolution Test... ${CRed}[Failed] ${CDkGray}| nslookup google.com${CClear}" + NetworkResTest="Failed" + fi + echo "" + fi + + printf "${InvYellow} ${CClear} ${CWhite}Dig Functionality Test... ${CYellow}[Checking] ${CDkGray}| dig google.com${CClear}" + DIG_STATE="$(dig google.com >/dev/null 2>&1; echo $?)" + sleep 1 + if [ "$DIG_STATE" = "0" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Dig Functionality Test... ${CGreen}[Passed] ${CDkGray}| dig google.com${CClear}" + DigFuncTest="Passed" + else + printf "\r${InvRed} ${CClear} ${CWhite}Dig Functionality Test... ${CRed}[Failed] ${CDkGray}| dig google.com${CClear}" + DigFuncTest="Failed" + fi + echo "" + + printf "${InvYellow} ${CClear} ${CWhite}Curl Functionality Test... ${CYellow}[Checking] ${CDkGray}| curl -Is http://www.google.com | head -n 1${CClear}" + CURL_STATE="$(curl -Is http://www.google.com | head -n 1 >/dev/null 2>&1; echo $?)" + sleep 1 + if [ "$CURL_STATE" = "0" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Curl Functionality Test... ${CGreen}[Passed] ${CDkGray}| curl -Is http://www.google.com | head -n 1${CClear}" + CurlFuncTest="Passed" + else + printf "\r${InvRed} ${CClear} ${CWhite}Curl Functionality Test... ${CRed}[Failed] ${CDkGray}| curl -Is http://www.google.com | head -n 1${CClear}" + CurlFuncTest="Failed" + fi + echo "" + + printf "${InvYellow} ${CClear} ${CWhite}Spider Functionality Test... ${CYellow}[Checking] ${CDkGray}| wget -q --spider http://google.com${CClear}" + SPIDER_STATE="$(wget -q --spider http://google.com >/dev/null 2>&1; echo $?)" + sleep 1 + if [ "$SPIDER_STATE" = "0" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Spider Functionality Test... ${CGreen}[Passed] ${CDkGray}| wget -q --spider http://google.com${CClear}" + SpiderFuncTest="Passed" + else + printf "\r${InvRed} ${CClear} ${CWhite}Spider Functionality Test... ${CRed}[Failed] ${CDkGray}| wget -q --spider http://google.com${CClear}" + SpiderFuncTest="Failed" + fi + echo "" + + printf "${InvYellow} ${CClear} ${CWhite}SSL Handshake Test... ${CYellow}[Checking] ${CDkGray}| nc -w3 8.8.8.8 443 && echo | openssl s_client -connect 8.8.8.8:443>${CClear}" + SSL_STATE="$(nc -w3 8.8.8.8 443 >/dev/null 2>&1 && echo | openssl s_client -connect 8.8.8.8:443 >/dev/null 2>&1 | awk 'handshake && $1 == "Verification" { if ($2=="OK") exit; exit 1 } $1 $2 == "SSLhandshake" { handshake = 1 }' >/dev/null 2>&1; echo $?)" + sleep 1 + if [ "$SSL_STATE" = "0" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}SSL Handshake Test... ${CGreen}[Passed] ${CDkGray}| nc -w3 8.8.8.8 443 && echo | openssl s_client -connect 8.8.8.8:443>${CClear}" + SSLHandshakeTest="Passed" + else + printf "\r${InvRed} ${CClear} ${CWhite}SSL Handshake Test... ${CRed}[Failed] ${CDkGray}| nc -w3 8.8.8.8 443 && echo | openssl s_client -connect 8.8.8.8:443>${CClear}" + SSLHandshakeTest="Failed" + fi + echo "" + echo "" + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} NMAP Port Scan Results ${CClear}" + + if [ "$PSView" == "TCP" ]; then + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} Show Open ${InvDkGray} ${CGreen}(T)${CWhite}CP ${CClear}${CWhite} Ports | Show Open ${CGreen}(U)${CWhite}DP Ports${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo "" + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + echo -e "${InvGreen} ${CClear} ${CWhite}WAN0 IP: ${CGreen}$oldwan0ip${CClear}" + WANnmap=$(nmap $oldwan0ip | grep "open") + if [ -z "$WANnmap" ]; then echo "None"; else nmap $oldwan0ip | grep "open"; fi + echo "" + fi + echo -e "${InvGreen} ${CClear} ${CWhite}BR0 IP: ${CGreen}$oldlanip${CClear}" + LANnmap=$(nmap $oldlanip | grep "open") + if [ -z "$LANnmap" ]; then echo "None"; else nmap $oldlanip | grep "open"; fi + elif [ "$PSView" == "UDP" ]; then + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} Show Open ${CGreen}(T)${CWhite}CP Ports | Show Open ${InvDkGray} ${CGreen}(U)${CWhite}DP ${CClear}${CWhite} Ports${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo "" + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + echo -e "${InvGreen} ${CClear} ${CWhite}WAN0 IP: ${CGreen}$oldwan0ip${CClear}" + WANUnmap=$(nmap -sU $oldwan0ip | grep "open") + if [ -z "$WANUnmap" ]; then echo "None"; else nmap -sU $oldwan0ip | grep "open"; fi + echo "" + fi + echo -e "${InvGreen} ${CClear} ${CWhite}BR0 IP: ${CGreen}$oldlanip${CClear}" + LANUnmap=$(nmap -sU $oldlanip | grep "open") + if [ -z "$LANUnmap" ]; then echo "None"; else nmap -sU $oldlanip | grep "open"; fi + fi + + { echo 'Lastruntime="'"$(date)"'"' + echo 'LocalClockTest="'"$LocalClockTest"'"' + echo 'NetworkConnTest="'"$NetworkConnTest"'"' + echo 'NetworkResTest="'"$NetworkResTest"'"' + echo 'DigFuncTest="'"$DigFuncTest"'"' + echo 'CurlFuncTest="'"$CurlFuncTest"'"' + echo 'SpiderFuncTest="'"$SpiderFuncTest"'"' + echo 'SSLHandshakeTest="'"$SSLHandshakeTest"'"' + } > $DIAGRESPATH + + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + nmap $oldwan0ip -oN $NMAPWANRESPATH | grep "open" >/dev/null 2>&1 + nmap $oldwan0ip -sU -oN $NMAPUWANRESPATH | grep "open" >/dev/null 2>&1 + fi + + nmap $oldlanip -oN $NMAPLANRESPATH | grep "open" >/dev/null 2>&1 + nmap $oldlanip -sU -oN $NMAPULANRESPATH | grep "open" >/dev/null 2>&1 + + QueueNetworkDiag=0 + +else + + if [ "$LocalClockTest" == "Passed" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Local Clock Test... ${CGreen}[Passed] ${CDkGray}| date > 1970${CClear}" + else + printf "\r${InvRed} ${CClear} ${CWhite}Local Clock Test... ${CRed}[Failed] ${CDkGray}| date > 1970${CClear}" + fi + echo "" + if [ "$NetworkConnTest" == "Passed" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Network Connectivity Test... ${CGreen}[Passed] ${CDkGray}| ping 1.1.1.1 -c1 -W2${CClear}" + else + printf "\r${InvRed} ${CClear} ${CWhite}Network Connectivity Test... ${CRed}[Failed] ${CDkGray}| ping 1.1.1.1 -c1 -W2${CClear}" + fi + echo "" + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + if [ "$NetworkResTest" == "Passed" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Network Resolution Test... ${CGreen}[Passed] ${CDkGray}| nslookup google.com 127.0.0.1${CClear}" + else + printf "\r${InvRed} ${CClear} ${CWhite}Network Resolution Test... ${CRed}[Failed] ${CDkGray}| nslookup google.com 127.0.0.1${CClear}" + fi + else + if [ "$NetworkResTest" == "Passed" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Network Resolution Test... ${CGreen}[Passed] ${CDkGray}| nslookup google.com${CClear}" + else + printf "\r${InvRed} ${CClear} ${CWhite}Network Resolution Test... ${CRed}[Failed] ${CDkGray}| nslookup google.com${CClear}" + fi + fi + echo "" + if [ "$DigFuncTest" == "Passed" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Dig Functionality Test... ${CGreen}[Passed] ${CDkGray}| dig google.com${CClear}" + else + printf "\r${InvRed} ${CClear} ${CWhite}Dig Functionality Test... ${CRed}[Failed] ${CDkGray}| dig google.com${CClear}" + fi + echo "" + if [ "$CurlFuncTest" == "Passed" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Curl Functionality Test... ${CGreen}[Passed] ${CDkGray}| curl -Is http://www.google.com | head -n 1${CClear}" + else + printf "\r${InvRed} ${CClear} ${CWhite}Curl Functionality Test... ${CRed}[Failed] ${CDkGray}| curl -Is http://www.google.com | head -n 1${CClear}" + fi + echo "" + if [ "$SpiderFuncTest" == "Passed" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Spider Functionality Test... ${CGreen}[Passed] ${CDkGray}| wget -q --spider http://google.com${CClear}" + else + printf "\r${InvRed} ${CClear} ${CWhite}Spider Functionality Test... ${CRed}[Failed] ${CDkGray}| wget -q --spider http://google.com${CClear}" + fi + echo "" + if [ "$SSLHandshakeTest" == "Passed" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}SSL Handshake Test... ${CGreen}[Passed] ${CDkGray}| nc -w3 8.8.8.8 443 && echo | openssl s_client -connect 8.8.8.8:443>${CClear}" + else + printf "\r${InvRed} ${CClear} ${CWhite}SSL Handshake Test... ${CRed}[Failed] ${CDkGray}| nc -w3 8.8.8.8 443 && echo | openssl s_client -connect 8.8.8.8:443>${CClear}" + fi + echo "" + echo "" + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} NMAP Port Scan Results ${CClear}" + + if [ "$PSView" == "TCP" ]; then + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} Show Open ${InvDkGray} ${CGreen}(T)${CWhite}CP ${CClear}${CWhite} Ports | Show Open ${CGreen}(U)${CWhite}DP Ports${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo "" + if [ "$ScreenshotMode" == "1" ]; then + oldwan0ip="12.34.56.78" #demo + fi + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + echo -e "${InvGreen} ${CClear} ${CWhite}WAN0 IP: ${CGreen}$oldwan0ip${CClear}" + if [ ! -f $NMAPWANRESPATH ]; then + echo "None" + else + WANnmap=$(cat $NMAPWANRESPATH | grep "open") + if [ -z "$WANnmap" ]; then echo "None"; else cat $NMAPWANRESPATH | grep "open"; fi + fi + echo "" + fi + echo -e "${InvGreen} ${CClear} ${CWhite}BR0 IP: ${CGreen}$oldlanip${CClear}" + if [ ! -f $NMAPLANRESPATH ]; then + echo "None" + else + LANnmap=$(cat $NMAPLANRESPATH | grep "open") + if [ -z "$LANnmap" ]; then echo "None"; else cat $NMAPLANRESPATH | grep "open"; fi + fi + elif [ "$PSView" == "UDP" ]; then + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} Show Open ${CGreen}(T)${CWhite}CP Ports | Show Open ${InvDkGray} ${CGreen}(U)${CWhite}DP ${CClear}${CWhite} Ports${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo "" + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + echo -e "${InvGreen} ${CClear} ${CWhite}WAN0 IP: ${CGreen}$oldwan0ip${CClear}" + if [ ! -f $NMAPUWANRESPATH ]; then + echo "None" + else + WANUnmap=$(cat $NMAPUWANRESPATH | grep "open") + if [ -z "$WANUnmap" ]; then echo "None"; else cat $NMAPUWANRESPATH | grep "open"; fi + fi + echo "" + fi + echo -e "${InvGreen} ${CClear} ${CWhite}BR0 IP: ${CGreen}$oldlanip${CClear}" + if [ ! -f $NMAPULANRESPATH ]; then + echo "None" + else + LANUnmap=$(cat $NMAPULANRESPATH | grep "open") + if [ -z "$LANUnmap" ]; then echo "None"; else cat $NMAPULANRESPATH | grep "open"; fi + fi + fi +fi +} + +# ------------------------------------------------------------------------------------------------------------------------- + +# This function displays the stats UI for page 6 which includes top bandwidth connections for WAN, LAN and VPN +DisplayPage6() +{ + clear + if [ "$UpdateNotify" != "0" ]; then + echo -e "$UpdateNotify${CClear}" + fi + showheader + echo "" + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} Top 10 Network Connections/Bandwidth Stats ${CClear}" + echo -e "${InvGreen} ${CClear}" + + if [ "$QueueNetworkConn" = "1" ] + then + #run network diags and save Results + printf "${InvGreen} ${CClear} ${CWhite}[Updating WAN( ) LAN( ) VPN( ) WG( ) Statistics ... Please stand by...]" + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + timeout 15 iftop -t -s 10 -i $WANIFNAME 2>&1 | sed '/^==/ q' > /jffs/addons/rtrmon.d/wanresult.txt + fi + printf "\r${InvGreen} ${CClear} ${CWhite}[Updating WAN(${CGreen}X${CWhite}) LAN( ) VPN( ) WG( ) Statistics ... Please stand by...]" + timeout 15 iftop -t -s 10 -i br0 2>&1 | sed '/^==/ q' > /jffs/addons/rtrmon.d/lanresult.txt + printf "\r${InvGreen} ${CClear} ${CWhite}[Updating WAN(${CGreen}X${CWhite}) LAN(${CGreen}X${CWhite}) VPN( ) WG( ) Statistics ... Please stand by...]" + + if [ "$vpn1on" == "True" ] || [ "$vpn2on" == "True" ] || [ "$vpn3on" == "True" ] || [ "$vpn4on" == "True" ] || [ "$vpn5on" == "True" ] + then + slot=0 + while [ "$slot" -ne 5 ] + do + slot="$((slot+1))" + selectedslot="vpn${slot}on" + eval selectedslot="\$${selectedslot}" + if [ "$selectedslot" = "True" ] && [ "$VPNSite2Site" = "0" ] + then + NVRAMVPNSLOTADDR=$($timeoutcmd$timeoutsec nvram get vpn_client"$slot"_addr) + NVRAMVPNSLOTIP=$(ping -c 1 -w 1 $NVRAMVPNSLOTADDR | awk -F '[()]' '/PING/ { print $2}') + if [ "$(echo "$NVRAMVPNSLOTIP" | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then + { echo 'Private Tunnel' + } > /jffs/addons/rtrmon.d/vpn${slot}result.txt + else + timeout 15 iftop -t -s 10 -i tun1$slot 2>&1 | sed '/^==/ q' > /jffs/addons/rtrmon.d/vpn${slot}result.txt + fi + fi + done + fi + + printf "\r${InvGreen} ${CClear} ${CWhite}[Updating WAN(${CGreen}X${CWhite}) LAN(${CGreen}X${CWhite}) VPN(${CGreen}X${CWhite}) WG( ) Statistics ... Please stand by...]" + + if [ "$wg1on" == "True" ] || [ "$wg2on" == "True" ] || [ "$wg3on" == "True" ] || [ "$wg4on" == "True" ] || [ "$wg5on" == "True" ] + then + slot=0 + while [ "$slot" -ne 5 ] + do + slot="$((slot+1))" + selectedslot="wg${slot}on" + eval selectedslot="\$${selectedslot}" + if [ "$selectedslot" = "True" ] && [ "$VPNSite2Site" = "0" ] + then + WGTUN="wgc$slot" + NVRAMWGSLOTADDR=$($timeoutcmd$timeoutsec nvram get "$WGTUN"_addr | cut -d '/' -f1) + + # Added based on suggestion from @ZebMcKayhan + ip rule add from $NVRAMWGSLOTADDR lookup $WGTUN prio 10 >/dev/null 2>&1 + + icanhazwgip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN" --request GET --url https://ipv4.icanhazip.com" + icanhazwgip="$(eval $icanhazwgip)" + if [ -z "$icanhazwgip" ] || echo "$icanhazwgip" | grep -qoE 'Internet|traffic|Error|error' + then + { echo 'Error determining WG$slot IP' + } > /jffs/addons/rtrmon.d/wgc${slot}result.txt + else + NVRAMWGIP="$icanhazwgip" + fi + + # Added based on suggestion from @ZebMcKayhan + ip rule del prio 10 >/dev/null 2>&1 + + if [ "$(echo "$NVRAMWGIP" | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then + { echo 'Private Tunnel' + } > /jffs/addons/rtrmon.d/wgc${slot}result.txt + else + timeout 15 iftop -t -s 10 -i wgc$slot 2>&1 | sed '/^==/ q' > /jffs/addons/rtrmon.d/wgc${slot}result.txt + fi + fi + done + fi + + printf "\r${InvGreen} ${CClear} ${CWhite}[Updating WAN(${CGreen}X${CWhite}) LAN(${CGreen}X${CWhite}) VPN(${CGreen}X${CWhite}) WG(${CGreen}X${CWhite}) Statistics ... Please stand by...]" + sleep 1 + printf "\r " + QueueNetworkConn=0 + testrun="$(date +%s)" + + if [ -z "${testrun:+xSETx}" ] + then + lastrun="Not Current" + else + currtime="$(date +%s)" + mindiffs="$(( ($currtime - $testrun)/60 ))" + lastrun="$mindiffs Minute(s) ago" + fi + + echo -e "\r${InvGreen} ${CClear} ${CWhite}Refresh ${CGreen}(C)${CWhite}urrent Statistics | Stats Age: ${CGreen}$lastrun${CClear}" + else + if [ -z "${testrun:+xSETx}" ] + then + lastrun="Not Current" + else + currtime="$(date +%s)" + mindiffs="$(( ($currtime - $testrun)/60 ))" + lastrun="$mindiffs Minute(s) ago" + fi + echo -e "${InvGreen} ${CClear} ${CWhite}Refresh ${CGreen}(C)${CWhite}urrent Statistics | Stats Age: ${CGreen}$lastrun${CClear}" + fi + + if [ "$NCView" == "WAN" ]; then + if [ "$vpn1on" == "True" ] || [ "$vpn2on" == "True" ] || [ "$vpn3on" == "True" ] || [ "$vpn4on" == "True" ] || [ "$vpn5on" == "True" ] || [ "$wg1on" == "True" ] || [ "$wg2on" == "True" ] || [ "$wg3on" == "True" ] || [ "$wg4on" == "True" ] || [ "$wg5on" == "True" ]; then + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} View ${InvDkGray} ${CGreen}(W)${CWhite}AN ${CClear}${CWhite} | ${CGreen}(L)${CWhite}AN | ${CGreen}(V)${CWhite}PN | W${CGreen}(G)${CClear}" + else + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} View ${InvDkGray} ${CGreen}(W)${CWhite}AN ${CClear}${CWhite} | ${CGreen}(L)${CWhite}AN${CClear}" + fi + + echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} WAN ${CClear}" + + wansegments1=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==7 {print $1, $2, $4} NR==8 {print $1, $3}') + + line1="$(echo $wansegments1 | awk '{print $1}')" + dest1="$(echo $wansegments1 | awk '{print $2}')" + out1="$(echo $wansegments1 | awk '{print $3}')" + src1="$(echo $wansegments1 | awk '{print $4}')" + in1="$(echo $wansegments1 | awk '{print $5}')" + + wansegments2=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==9 {print $1, $2, $4} NR==10 {print $1, $3}') + + line2="$(echo $wansegments2 | awk '{print $1}')" + dest2="$(echo $wansegments2 | awk '{print $2}')" + out2="$(echo $wansegments2 | awk '{print $3}')" + src2="$(echo $wansegments2 | awk '{print $4}')" + in2="$(echo $wansegments2 | awk '{print $5}')" + + wansegments3=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==11 {print $1, $2, $4} NR==12 {print $1, $3}') + + line3="$(echo $wansegments3 | awk '{print $1}')" + dest3="$(echo $wansegments3 | awk '{print $2}')" + out3="$(echo $wansegments3 | awk '{print $3}')" + src3="$(echo $wansegments3 | awk '{print $4}')" + in3="$(echo $wansegments3 | awk '{print $5}')" + + wansegments4=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==13 {print $1, $2, $4} NR==14 {print $1, $3}') + + line4="$(echo $wansegments4 | awk '{print $1}')" + dest4="$(echo $wansegments4 | awk '{print $2}')" + out4="$(echo $wansegments4 | awk '{print $3}')" + src4="$(echo $wansegments4 | awk '{print $4}')" + in4="$(echo $wansegments4 | awk '{print $5}')" + + wansegments5=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==15 {print $1, $2, $4} NR==16 {print $1, $3}') + + line5="$(echo $wansegments5 | awk '{print $1}')" + dest5="$(echo $wansegments5 | awk '{print $2}')" + out5="$(echo $wansegments5 | awk '{print $3}')" + src5="$(echo $wansegments5 | awk '{print $4}')" + in5="$(echo $wansegments5 | awk '{print $5}')" + + wansegments6=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==17 {print $1, $2, $4} NR==18 {print $1, $3}') + + line6="$(echo $wansegments6 | awk '{print $1}')" + dest6="$(echo $wansegments6 | awk '{print $2}')" + out6="$(echo $wansegments6 | awk '{print $3}')" + src6="$(echo $wansegments6 | awk '{print $4}')" + in6="$(echo $wansegments6 | awk '{print $5}')" + + wansegments7=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==19 {print $1, $2, $4} NR==20 {print $1, $3}') + + line7="$(echo $wansegments7 | awk '{print $1}')" + dest7="$(echo $wansegments7 | awk '{print $2}')" + out7="$(echo $wansegments7 | awk '{print $3}')" + src7="$(echo $wansegments7 | awk '{print $4}')" + in7="$(echo $wansegments7 | awk '{print $5}')" + + wansegments8=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==21 {print $1, $2, $4} NR==22 {print $1, $3}') + + line8="$(echo $wansegments8 | awk '{print $1}')" + dest8="$(echo $wansegments8 | awk '{print $2}')" + out8="$(echo $wansegments8 | awk '{print $3}')" + src8="$(echo $wansegments8 | awk '{print $4}')" + in8="$(echo $wansegments8 | awk '{print $5}')" + + wansegments9=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==23 {print $1, $2, $4} NR==24 {print $1, $3}') + + line9="$(echo $wansegments9 | awk '{print $1}')" + dest9="$(echo $wansegments9 | awk '{print $2}')" + out9="$(echo $wansegments9 | awk '{print $3}')" + src9="$(echo $wansegments9 | awk '{print $4}')" + in9="$(echo $wansegments9 | awk '{print $5}')" + + wansegments10=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==25 {print $1, $2, $4} NR==26 {print $1, $3}') + + line10="$(echo $wansegments10 | awk '{print $1}')" + dest10="$(echo $wansegments10 | awk '{print $2}')" + out10="$(echo $wansegments10 | awk '{print $3}')" + src10="$(echo $wansegments10 | awk '{print $4}')" + in10="$(echo $wansegments10 | awk '{print $5}')" + + if [ "$line1" == "1" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line1 $dest1 <=> $src1" " Out: $out1 | In: $in1" + else + echo "No Data" + fi + + if [ "$line2" == "2" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line2 $dest2 <=> $src2" " Out: $out2 | In: $in2" + fi + + if [ "$line3" == "3" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line3 $dest3 <=> $src3" " Out: $out3 | In: $in3" + fi + + if [ "$line4" == "4" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line4 $dest4 <=> $src4" " Out: $out4 | In: $in4" + fi + + if [ "$line5" == "5" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line5 $dest5 <=> $src5" " Out: $out5 | In: $in5" + fi + + if [ "$line6" == "6" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line6 $dest6 <=> $src6" " Out: $out6 | In: $in6" + fi + + if [ "$line7" == "7" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line7 $dest7 <=> $src7" " Out: $out7 | In: $in7" + fi + + if [ "$line8" == "8" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line8 $dest8 <=> $src8" " Out: $out8 | In: $in8" + fi + + if [ "$line9" == "9" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line9 $dest9 <=> $src9" " Out: $out9 | In: $in9" + fi + + if [ "$line10" == "10" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" "$line10 $dest10 <=> $src10" " Out: $out10 | In: $in10" + fi + fi + + if [ "$NCView" == "LAN" ]; then + if [ "$vpn1on" == "True" ] || [ "$vpn2on" == "True" ] || [ "$vpn3on" == "True" ] || [ "$vpn4on" == "True" ] || [ "$vpn5on" == "True" ] || [ "$wg1on" == "True" ] || [ "$wg2on" == "True" ] || [ "$wg3on" == "True" ] || [ "$wg4on" == "True" ] || [ "$wg5on" == "True" ]; then + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} View ${CGreen}(W)${CWhite}AN | ${InvDkGray} ${CGreen}(L)${CWhite}AN ${CClear}${CWhite} | ${CGreen}(V)${CWhite}PN | W${CGreen}(G)${CClear}" + else + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} View ${CGreen}(W)${CWhite}AN | ${InvDkGray} ${CGreen}(L)${CWhite}AN ${CClear}" + fi + + echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo "" + + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} LAN ${CClear}" + + lansegments1=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==7 {print $1, $2, $4} NR==8 {print $1, $3}') + + line1="$(echo $lansegments1 | awk '{print $1}')" + dest1="$(echo $lansegments1 | awk '{print $2}')" + out1="$(echo $lansegments1 | awk '{print $3}')" + src1="$(echo $lansegments1 | awk '{print $4}')" + in1="$(echo $lansegments1 | awk '{print $5}')" + + lansegments2=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==9 {print $1, $2, $4} NR==10 {print $1, $3}') + + line2="$(echo $lansegments2 | awk '{print $1}')" + dest2="$(echo $lansegments2 | awk '{print $2}')" + out2="$(echo $lansegments2 | awk '{print $3}')" + src2="$(echo $lansegments2 | awk '{print $4}')" + in2="$(echo $lansegments2 | awk '{print $5}')" + + lansegments3=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==11 {print $1, $2, $4} NR==12 {print $1, $3}') + + line3="$(echo $lansegments3 | awk '{print $1}')" + dest3="$(echo $lansegments3 | awk '{print $2}')" + out3="$(echo $lansegments3 | awk '{print $3}')" + src3="$(echo $lansegments3 | awk '{print $4}')" + in3="$(echo $lansegments3 | awk '{print $5}')" + + lansegments4=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==13 {print $1, $2, $4} NR==14 {print $1, $3}') + + line4="$(echo $lansegments4 | awk '{print $1}')" + dest4="$(echo $lansegments4 | awk '{print $2}')" + out4="$(echo $lansegments4 | awk '{print $3}')" + src4="$(echo $lansegments4 | awk '{print $4}')" + in4="$(echo $lansegments4 | awk '{print $5}')" + + lansegments5=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==15 {print $1, $2, $4} NR==16 {print $1, $3}') + + line5="$(echo $lansegments5 | awk '{print $1}')" + dest5="$(echo $lansegments5 | awk '{print $2}')" + out5="$(echo $lansegments5 | awk '{print $3}')" + src5="$(echo $lansegments5 | awk '{print $4}')" + in5="$(echo $lansegments5 | awk '{print $5}')" + + lansegments6=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==17 {print $1, $2, $4} NR==18 {print $1, $3}') + + line6="$(echo $lansegments6 | awk '{print $1}')" + dest6="$(echo $lansegments6 | awk '{print $2}')" + out6="$(echo $lansegments6 | awk '{print $3}')" + src6="$(echo $lansegments6 | awk '{print $4}')" + in6="$(echo $lansegments6 | awk '{print $5}')" + + lansegments7=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==19 {print $1, $2, $4} NR==20 {print $1, $3}') + + line7="$(echo $lansegments7 | awk '{print $1}')" + dest7="$(echo $lansegments7 | awk '{print $2}')" + out7="$(echo $lansegments7 | awk '{print $3}')" + src7="$(echo $lansegments7 | awk '{print $4}')" + in7="$(echo $lansegments7 | awk '{print $5}')" + + lansegments8=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==21 {print $1, $2, $4} NR==22 {print $1, $3}') + + line8="$(echo $lansegments8 | awk '{print $1}')" + dest8="$(echo $lansegments8 | awk '{print $2}')" + out8="$(echo $lansegments8 | awk '{print $3}')" + src8="$(echo $lansegments8 | awk '{print $4}')" + in8="$(echo $lansegments8 | awk '{print $5}')" + + lansegments9=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==23 {print $1, $2, $4} NR==24 {print $1, $3}') + + line9="$(echo $lansegments9 | awk '{print $1}')" + dest9="$(echo $lansegments9 | awk '{print $2}')" + out9="$(echo $lansegments9 | awk '{print $3}')" + src9="$(echo $lansegments9 | awk '{print $4}')" + in9="$(echo $lansegments9 | awk '{print $5}')" + + lansegments10=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==25 {print $1, $2, $4} NR==26 {print $1, $3}') + + line10="$(echo $lansegments10 | awk '{print $1}')" + dest10="$(echo $lansegments10 | awk '{print $2}')" + out10="$(echo $lansegments10 | awk '{print $3}')" + src10="$(echo $lansegments10 | awk '{print $4}')" + in10="$(echo $lansegments10 | awk '{print $5}')" + + if [ "$line1" == "1" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line1 $dest1 <=> $src1" " Out: $out1 | In: $in1" + else + echo "No Data" + fi + + if [ "$line2" == "2" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line2 $dest2 <=> $src2" " Out: $out2 | In: $in2" + fi + + if [ "$line3" == "3" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line3 $dest3 <=> $src3" " Out: $out3 | In: $in3" + fi + + if [ "$line4" == "4" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line4 $dest4 <=> $src4" " Out: $out4 | In: $in4" + fi + + if [ "$line5" == "5" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line5 $dest5 <=> $src5" " Out: $out5 | In: $in5" + fi + + if [ "$line6" == "6" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line6 $dest6 <=> $src6" " Out: $out6 | In: $in6" + fi + + if [ "$line7" == "7" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line7 $dest7 <=> $src7" " Out: $out7 | In: $in7" + fi + + if [ "$line8" == "8" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line8 $dest8 <=> $src8" " Out: $out8 | In: $in8" + fi + + if [ "$line9" == "9" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line9 $dest9 <=> $src9" " Out: $out9 | In: $in9" + fi + + if [ "$line10" == "10" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" "$line10 $dest10 <=> $src10" " Out: $out10 | In: $in10" + fi + fi + + if [ "$NCView" = "VPN" ] + then + if [ "$vpn1on" == "True" ] || [ "$vpn2on" == "True" ] || [ "$vpn3on" == "True" ] || [ "$vpn4on" == "True" ] || [ "$vpn5on" == "True" ] || [ "$wg1on" == "True" ] || [ "$wg2on" == "True" ] || [ "$wg3on" == "True" ] || [ "$wg4on" == "True" ] || [ "$wg5on" == "True" ]; then + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} View ${CGreen}(W)${CWhite}AN ${CWhite}| ${CGreen}(L)${CWhite}AN | ${InvDkGray} ${CGreen}(V)${CWhite}PN ${CClear} ${CWhite}| W${CGreen}(G)${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo "" + + slot=0 + while [ "$slot" -ne 5 ] + do + slot="$((slot+1))" + selectedslot="vpn${slot}on" + eval selectedslot="\$${selectedslot}" + if [ "$selectedslot" = "True" ] && [ "$VPNSite2Site" = "0" ] + then + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} VPN$slot ${CClear}" + + vpnsegments1=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==7 {print $1, $2, $4} NR==8 {print $1, $3}') + + line1="$(echo $vpnsegments1 | awk '{print $1}')" + dest1="$(echo $vpnsegments1 | awk '{print $2}')" + out1="$(echo $vpnsegments1 | awk '{print $3}')" + src1="$(echo $vpnsegments1 | awk '{print $4}')" + in1="$(echo $vpnsegments1 | awk '{print $5}')" + + vpnsegments2=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==9 {print $1, $2, $4} NR==10 {print $1, $3}') + + line2="$(echo $vpnsegments2 | awk '{print $1}')" + dest2="$(echo $vpnsegments2 | awk '{print $2}')" + out2="$(echo $vpnsegments2 | awk '{print $3}')" + src2="$(echo $vpnsegments2 | awk '{print $4}')" + in2="$(echo $vpnsegments2 | awk '{print $5}')" + + vpnsegments3=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==11 {print $1, $2, $4} NR==12 {print $1, $3}') + + line3="$(echo $vpnsegments3 | awk '{print $1}')" + dest3="$(echo $vpnsegments3 | awk '{print $2}')" + out3="$(echo $vpnsegments3 | awk '{print $3}')" + src3="$(echo $vpnsegments3 | awk '{print $4}')" + in3="$(echo $vpnsegments3 | awk '{print $5}')" + + vpnsegments4=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==13 {print $1, $2, $4} NR==14 {print $1, $3}') + + line4="$(echo $vpnsegments4 | awk '{print $1}')" + dest4="$(echo $vpnsegments4 | awk '{print $2}')" + out4="$(echo $vpnsegments4 | awk '{print $3}')" + src4="$(echo $vpnsegments4 | awk '{print $4}')" + in4="$(echo $vpnsegments4 | awk '{print $5}')" + + vpnsegments5=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==15 {print $1, $2, $4} NR==16 {print $1, $3}') + + line5="$(echo $vpnsegments5 | awk '{print $1}')" + dest5="$(echo $vpnsegments5 | awk '{print $2}')" + out5="$(echo $vpnsegments5 | awk '{print $3}')" + src5="$(echo $vpnsegments5 | awk '{print $4}')" + in5="$(echo $vpnsegments5 | awk '{print $5}')" + + vpnsegments6=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==17 {print $1, $2, $4} NR==18 {print $1, $3}') + + line6="$(echo $vpnsegments6 | awk '{print $1}')" + dest6="$(echo $vpnsegments6 | awk '{print $2}')" + out6="$(echo $vpnsegments6 | awk '{print $3}')" + src6="$(echo $vpnsegments6 | awk '{print $4}')" + in6="$(echo $vpnsegments6 | awk '{print $5}')" + + vpnsegments7=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==19 {print $1, $2, $4} NR==20 {print $1, $3}') + + line7="$(echo $vpnsegments7 | awk '{print $1}')" + dest7="$(echo $vpnsegments7 | awk '{print $2}')" + out7="$(echo $vpnsegments7 | awk '{print $3}')" + src7="$(echo $vpnsegments7 | awk '{print $4}')" + in7="$(echo $vpnsegments7 | awk '{print $5}')" + + vpnsegments8=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==21 {print $1, $2, $4} NR==22 {print $1, $3}') + + line8="$(echo $vpnsegments8 | awk '{print $1}')" + dest8="$(echo $vpnsegments8 | awk '{print $2}')" + out8="$(echo $vpnsegments8 | awk '{print $3}')" + src8="$(echo $vpnsegments8 | awk '{print $4}')" + in8="$(echo $vpnsegments8 | awk '{print $5}')" + + vpnsegments9=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==23 {print $1, $2, $4} NR==24 {print $1, $3}') + + line9="$(echo $vpnsegments9 | awk '{print $1}')" + dest9="$(echo $vpnsegments9 | awk '{print $2}')" + out9="$(echo $vpnsegments9 | awk '{print $3}')" + src9="$(echo $vpnsegments9 | awk '{print $4}')" + in9="$(echo $vpnsegments9 | awk '{print $5}')" + + vpnsegments10=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==25 {print $1, $2, $4} NR==26 {print $1, $3}') + + line10="$(echo $vpnsegments10 | awk '{print $1}')" + dest10="$(echo $vpnsegments10 | awk '{print $2}')" + out10="$(echo $vpnsegments10 | awk '{print $3}')" + src10="$(echo $vpnsegments10 | awk '{print $4}')" + in10="$(echo $vpnsegments10 | awk '{print $5}')" + + if [ "$line1" == "1" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line1 $dest1 <=> $src1" " Out: $out1 | In: $in1" + else + echo "No Data" + fi + + if [ "$line2" == "2" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line2 $dest2 <=> $src2" " Out: $out2 | In: $in2" + fi + + if [ "$line3" == "3" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line3 $dest3 <=> $src3" " Out: $out3 | In: $in3" + fi + + if [ "$line4" == "4" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line4 $dest4 <=> $src4" " Out: $out4 | In: $in4" + fi + + if [ "$line5" == "5" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line5 $dest5 <=> $src5" " Out: $out5 | In: $in5" + fi + + if [ "$line6" == "6" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line6 $dest6 <=> $src6" " Out: $out6 | In: $in6" + fi + + if [ "$line7" == "7" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line7 $dest7 <=> $src7" " Out: $out7 | In: $in7" + fi + + if [ "$line8" == "8" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line8 $dest8 <=> $src8" " Out: $out8 | In: $in8" + fi + + if [ "$line9" == "9" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line9 $dest9 <=> $src9" " Out: $out9 | In: $in9" + fi + + if [ "$line10" == "10" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" "$line10 $dest10 <=> $src10" " Out: $out10 | In: $in10" + fi + + echo "" + fi + done + fi + fi + +if [ "$NCView" = "WG" ] + then + if [ "$vpn1on" == "True" ] || [ "$vpn2on" == "True" ] || [ "$vpn3on" == "True" ] || [ "$vpn4on" == "True" ] || [ "$vpn5on" == "True" ] || [ "$wg1on" == "True" ] || [ "$wg2on" == "True" ] || [ "$wg3on" == "True" ] || [ "$wg4on" == "True" ] || [ "$wg5on" == "True" ]; then + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} View ${CGreen}(W)${CWhite}AN ${CWhite}| ${CGreen}(L)${CWhite}AN | ${CGreen}(V)${CWhite}PN | ${InvDkGray} W${CGreen}(G) ${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo "" + + slot=0 + while [ "$slot" -ne 5 ] + do + slot="$((slot+1))" + selectedslot="wg${slot}on" + eval selectedslot="\$${selectedslot}" + if [ "$selectedslot" = "True" ] && [ "$VPNSite2Site" = "0" ] + then + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} WG$slot ${CClear}" + + wgsegments1=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==7 {print $1, $2, $4} NR==8 {print $1, $3}') + + line1="$(echo $wgsegments1 | awk '{print $1}')" + dest1="$(echo $wgsegments1 | awk '{print $2}')" + out1="$(echo $wgsegments1 | awk '{print $3}')" + src1="$(echo $wgsegments1 | awk '{print $4}')" + in1="$(echo $wgsegments1 | awk '{print $5}')" + + wgsegments2=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==9 {print $1, $2, $4} NR==10 {print $1, $3}') + + line2="$(echo $wgsegments2 | awk '{print $1}')" + dest2="$(echo $wgsegments2 | awk '{print $2}')" + out2="$(echo $wgsegments2 | awk '{print $3}')" + src2="$(echo $wgsegments2 | awk '{print $4}')" + in2="$(echo $wgsegments2 | awk '{print $5}')" + + wgsegments3=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==11 {print $1, $2, $4} NR==12 {print $1, $3}') + + line3="$(echo $wgsegments3 | awk '{print $1}')" + dest3="$(echo $wgsegments3 | awk '{print $2}')" + out3="$(echo $wgsegments3 | awk '{print $3}')" + src3="$(echo $wgsegments3 | awk '{print $4}')" + in3="$(echo $wgsegments3 | awk '{print $5}')" + + wgsegments4=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==13 {print $1, $2, $4} NR==14 {print $1, $3}') + + line4="$(echo $wgsegments4 | awk '{print $1}')" + dest4="$(echo $wgsegments4 | awk '{print $2}')" + out4="$(echo $wgsegments4 | awk '{print $3}')" + src4="$(echo $wgsegments4 | awk '{print $4}')" + in4="$(echo $wgsegments4 | awk '{print $5}')" + + wgsegments5=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==15 {print $1, $2, $4} NR==16 {print $1, $3}') + + line5="$(echo $wgsegments5 | awk '{print $1}')" + dest5="$(echo $wgsegments5 | awk '{print $2}')" + out5="$(echo $wgsegments5 | awk '{print $3}')" + src5="$(echo $wgsegments5 | awk '{print $4}')" + in5="$(echo $wgsegments5 | awk '{print $5}')" + + wgsegments6=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==17 {print $1, $2, $4} NR==18 {print $1, $3}') + + line6="$(echo $wgsegments6 | awk '{print $1}')" + dest6="$(echo $wgsegments6 | awk '{print $2}')" + out6="$(echo $wgsegments6 | awk '{print $3}')" + src6="$(echo $wgsegments6 | awk '{print $4}')" + in6="$(echo $wgsegments6 | awk '{print $5}')" + + wgsegments7=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==19 {print $1, $2, $4} NR==20 {print $1, $3}') + + line7="$(echo $wgsegments7 | awk '{print $1}')" + dest7="$(echo $wgsegments7 | awk '{print $2}')" + out7="$(echo $wgsegments7 | awk '{print $3}')" + src7="$(echo $wgsegments7 | awk '{print $4}')" + in7="$(echo $wgsegments7 | awk '{print $5}')" + + wgsegments8=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==21 {print $1, $2, $4} NR==22 {print $1, $3}') + + line8="$(echo $wgsegments8 | awk '{print $1}')" + dest8="$(echo $wgsegments8 | awk '{print $2}')" + out8="$(echo $wgsegments8 | awk '{print $3}')" + src8="$(echo $wgsegments8 | awk '{print $4}')" + in8="$(echo $wgsegments8 | awk '{print $5}')" + + wgsegments9=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==23 {print $1, $2, $4} NR==24 {print $1, $3}') + + line9="$(echo $wgsegments9 | awk '{print $1}')" + dest9="$(echo $wgsegments9 | awk '{print $2}')" + out9="$(echo $wgsegments9 | awk '{print $3}')" + src9="$(echo $wgsegments9 | awk '{print $4}')" + in9="$(echo $wgsegments9 | awk '{print $5}')" + + wgsegments10=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==25 {print $1, $2, $4} NR==26 {print $1, $3}') + + line10="$(echo $wgsegments10 | awk '{print $1}')" + dest10="$(echo $wgsegments10 | awk '{print $2}')" + out10="$(echo $wgsegments10 | awk '{print $3}')" + src10="$(echo $wgsegments10 | awk '{print $4}')" + in10="$(echo $wgsegments10 | awk '{print $5}')" + + if [ "$line1" == "1" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line1 $dest1 <=> $src1" " Out: $out1 | In: $in1" + else + echo "No Data" + fi + + if [ "$line2" == "2" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line2 $dest2 <=> $src2" " Out: $out2 | In: $in2" + fi + + if [ "$line3" == "3" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line3 $dest3 <=> $src3" " Out: $out3 | In: $in3" + fi + + if [ "$line4" == "4" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line4 $dest4 <=> $src4" " Out: $out4 | In: $in4" + fi + + if [ "$line5" == "5" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line5 $dest5 <=> $src5" " Out: $out5 | In: $in5" + fi + + if [ "$line6" == "6" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line6 $dest6 <=> $src6" " Out: $out6 | In: $in6" + fi + + if [ "$line7" == "7" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line7 $dest7 <=> $src7" " Out: $out7 | In: $in7" + fi + + if [ "$line8" == "8" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line8 $dest8 <=> $src8" " Out: $out8 | In: $in8" + fi + + if [ "$line9" == "9" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line9 $dest9 <=> $src9" " Out: $out9 | In: $in9" + fi + + if [ "$line10" == "10" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" "$line10 $dest10 <=> $src10" " Out: $out10 | In: $in10" + fi + + echo "" + fi + done + fi + fi + +} + +# ------------------------------------------------------------------------------------------------------------------------- +##------------------------------------------## +## Modified by ExtremeFiretop [2024-Aug-06] ## +##------------------------------------------## +# This function displays the stats UI for page 3 +DisplayPage7() +{ + clear + if [ "$UpdateNotify" != "0" ]; then + echo -e "$UpdateNotify${CClear}" + fi + showheader + # Create a temp arp table of connected wifi/lan clients + cat /proc/net/arp > /jffs/addons/rtrmon.d/temparp.txt + + # Force create the processed clients list file + touch /jffs/addons/rtrmon.d/processed_clients.txt + # Force create the processed clients list file for VLAN + touch /jffs/addons/rtrmon.d/processed_vlanclients.txt + + # Per @Stephen Harrington's sugguestion, check NVRAM to see if Wifi is turned on, else mark them as disabled + if [ "$FourBandCustom55624" == "True" ]; then + if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then + MaxSpeed52GhzNow=0 + else + MaxSpeed52GhzNow=$MaxSpeed5Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then + MaxSpeed6GhzNow=0 + else + MaxSpeed6GhzNow=$MaxSpeed6Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl3_radio) -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + elif [ "$FourBandCustom56624" == "True" ]; then + if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then + MaxSpeed6GhzNow=0 + else + MaxSpeed6GhzNow=$MaxSpeed6Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then + MaxSpeed62GhzNow=0 + else + MaxSpeed62GhzNow=$MaxSpeed6Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl3_radio) -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + elif [ "$ThreeBand2456" == "True" ]; then + if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then + MaxSpeed6GhzNow=0 + else + MaxSpeed6GhzNow=$MaxSpeed6Ghz + fi + elif [ "$ThreeBand2455" == "True" ]; then + if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then + MaxSpeed52GhzNow=0 + else + MaxSpeed52GhzNow=$MaxSpeed5Ghz + fi + else + if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + fi + + if [ "$SortbyOpt" = "Name" ]; then + SortbyNum="1" + elif [ "$SortbyOpt" = "IP" ]; then + SortbyNum="2" + elif [ "$SortbyOpt" = "MAC" ]; then + SortbyNum="3" + else + SortbyNum="1" + fi + prevSortByOpt="$SortbyOpt" + + #Testing + #MaxSpeed24GhzNow=0 + #w24updown="UP" #testing + echo "" + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} Attached Wireless + Wired Clients ${CClear}" + if [ "$SortbyOpt" = "Name" ]; then + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} Sort By: ${InvDkGray}${CGreen} (!)${CWhite}Name ${CClear}${CWhite} | ${CGreen}(@)${CWhite}IP | ${CGreen}(#)${CWhite}MAC${CClear}" + elif [ "$SortbyOpt" = "IP" ]; then + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} Sort By: ${CGreen} (!)${CWhite}Name | ${InvDkGray} ${CGreen}(@)${CWhite}IP ${CClear}${CWhite} | ${CGreen}(#)${CWhite}MAC${CClear}" + elif [ "$SortbyOpt" = "MAC" ]; then + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} Sort By: ${CGreen} (!)${CWhite}Name | ${CGreen}(@)${CWhite}IP | ${InvDkGray} ${CGreen}(#)${CWhite}MAC ${CClear}" + fi + echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo "" + + if [ "$MaxSpeed24GhzNow" != "0" ]; then + if [ "$w24updown" == "UP" ]; then + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 2.4GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname24 ${CClear}" + else + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 2.4GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname24 ${CClear}" + fi + attachedwificlients "$ifname24" + echo "" + else + echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 2.4GHz ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" + echo "" + fi + #Testing + #MaxSpeed5GhzNow=0 #testing + #w5updown="UP" #testing + if [ "$MaxSpeed5GhzNow" != "0" ]; then + if [ "$w5updown" == "UP" ]; then + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname5 ${CClear}" + else + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname5 ${CClear}" + fi + attachedwificlients "$ifname5" + echo "" + else + echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" + echo "" + fi + #Testing + #FourBandCustom55624="True" #testing + #MaxSpeed52GhzNow=0 #testing + #w52updown="UP" #testing + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then + if [ "$MaxSpeed52GhzNow" != "0" ]; then + if [ "$w52updown" == "UP" ]; then + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz (2) ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname52 ${CClear}" + else + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz (2) ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname52 ${CClear}" + fi + attachedwificlients "$ifname52" + #attachedwificlients "$ifname5" #testing + echo "" + else + echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz (2) ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" + echo "" + fi + fi + #Testing + #ThreeBand2456="True" #testing + #MaxSpeed6GhzNow=1 #testing + #w6updown="UP" #testing + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then + if [ "$MaxSpeed6GhzNow" != "0" ]; then + if [ "$w6updown" == "UP" ]; then + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname6 ${CClear}" + else + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname6 ${CClear}" + fi + attachedwificlients "$ifname6" + #attachedwificlients "$ifname5" #testing + echo "" + else + echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" + echo "" + fi + fi + #Testing + #FourBandCustom56624="True" #testing + #MaxSpeed62GhzNow=0 #testing + #w62updown="UP" #testing + if [ "$FourBandCustom56624" == "True" ]; then + if [ "$MaxSpeed62GhzNow" != "0" ]; then + if [ "$w62updown" == "UP" ]; then + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz (2) ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname62 ${CClear}" + else + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz (2) ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname62 ${CClear}" + fi + attachedwificlients "$ifname62" + #attachedwificlients "$ifname5" #testing + echo "" + else + echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz (2) ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" + echo "" + fi + fi + + # Guest Network Clients - Thanks to @ColinTaylor for this methodology of stepping through legit guest network interfaces + cp -f /jffs/addons/rtrmon.d/temparp.txt /jffs/addons/rtrmon.d/temparpvlan.txt + for guestiface in $(nvram get wl0_vifs) $(nvram get wl1_vifs) $(nvram get wl2_vifs) $(nvram get wl3_vifs) + do + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local Guest Wi-Fi ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $guestiface ${CClear}" + attachedguestclients "$guestiface" + echo "" + done + + for vlanlabels in $(nvram get apg_ifnames) + do + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local VLAN/AiMesh VLAN ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $vlanlabels ${CClear}" + attachedvlanclients "$vlanlabels" + echo "" + done + + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local LAN/Non-VLAN AiMesh ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: br0 ${CClear}" + #Remove non-LAN records + sed -i -e '/eth0/d' /jffs/addons/rtrmon.d/temparp.txt + sed -i -e '/IP address/d' /jffs/addons/rtrmon.d/temparp.txt + sed -i -e '/00:00:00:00:00:00/d' /jffs/addons/rtrmon.d/temparp.txt + sed -i -e '/0x0/d' /jffs/addons/rtrmon.d/temparp.txt + attachedlanclients + rm -f /jffs/addons/rtrmon.d/processed_clients.txt + rm -f /jffs/addons/rtrmon.d/processed_vlanclients.txt + rm -f /jffs/addons/rtrmon.d/temparp.txt + + #Testing + #FourBandCustom55624="False" #testing + #MaxSpeed52GhzNow=0 #testing + #w52updown="UP" #testing + #ThreeBand2456="False" #testing + #MaxSpeed6GhzNow=0 #testing + #w6updown="UP" #testing + #FourBandCustom56624="False" #testing + #MaxSpeed62GhzNow=0 #testing + #w62updown="UP" #testing +} + +# ------------------------------------------------------------------------------------------------------------------------- +# multiple DHCP lists can exist. Read through all lists and compile into a single list. + +read_all_dhcp_leases() { + # Include the merged lease file if it exists + local lease_files="/var/lib/misc/dnsmasq-*.leases /var/lib/misc/dnsmasq.leases" + if [ -f "/tmp/dnsmasq-merged.leases" ]; then + lease_files="$lease_files /tmp/dnsmasq-merged.leases" + fi + local all_leases + all_leases=$(cat $lease_files 2>/dev/null) + echo "$all_leases" +} + +# Unified MLD MAC retrieval logic: given the current dhcpleases and association MAC (in lowercase), +# determine the lookup MAC (which may be the MLD MAC if present). +get_lookup_mac() { + local maclower="$1" + local leases="$2" + local lookup_mac="$maclower" + local mld_line field_count mld_mac + mld_line=$(echo "$leases" | grep -i "$maclower" | head -n1) + if [ -n "$mld_line" ]; then + field_count=$(echo "$mld_line" | awk '{print NF; exit}') + if [ "$field_count" -ge 5 ]; then + mld_mac=$(echo "$mld_line" | awk '{print $5; exit}') + if [ -n "$mld_mac" ] && [ "$mld_mac" != "*" ]; then + lookup_mac=$(echo "$mld_mac" | awk '{print tolower($0)}') + fi + fi + fi + echo "$lookup_mac" +} + +# attachedwificlients pulls connected client info from wl, arp and nvram +attachedwificlients () +{ + iface="$1" + rm -f /jffs/addons/rtrmon.d/wificlients$iface.txt + wl -i $iface assoclist > /jffs/addons/rtrmon.d/wificlients$iface.txt + maxclientcount=$(cat /jffs/addons/rtrmon.d/wificlients$iface.txt | wc -l) + rm -f /jffs/addons/rtrmon.d/clientlist$iface.txt + dhcpleases="$(read_all_dhcp_leases)" + local clients=$(nvram get custom_clientlist) + local maxextractcount=$(echo "$clients" | awk -F'>>' '{count=0; for (i=1; i<=NF; i++) if ($i != "") count++; print count}') + + local clientcount=0 + while [ $clientcount -le $maxclientcount ] + do + clientname="" + conntime="" + clientip="" + paddedclientip="" + clientcount=$((clientcount+1)) + local clientmac=$(awk 'NR=='$clientcount' {print $2}' /jffs/addons/rtrmon.d/wificlients$iface.txt) + + if [ -z "$clientmac" ]; then + continue + fi + + networktime=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/in network/ {print $3}') 2>/dev/null + conntime=$(date -d@$networktime -u +%Hh:%Mm) 2>/dev/null + txtotalbytes=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/tx total bytes:/ {print $4}') 2>/dev/null + rxtotalbytes=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rx data bytes:/ {print $4}') 2>/dev/null + txratekbps=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rate of last tx pkt:/ {print $6}') 2>/dev/null + rxratekbps=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rate of last rx pkt:/ {print $6}') 2>/dev/null + sigstrength=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/smoothed rssi:/ {print $3}') 2>/dev/null + maclower=$(echo "$clientmac" | awk '{print tolower($0)}') 2>/dev/null + + # --- Unified MLD MAC retrieval logic --- + lookup_mac=$(get_lookup_mac "$maclower" "$dhcpleases") + + # Find IPs for the given MAC address in the ARP table + ips=$(grep "$maclower" "/jffs/addons/rtrmon.d/temparp.txt" | awk '{print $1}') 2>/dev/null + + # Iterate over the IPs to find the reachable one + for ip in $ips; do + # Check the status of the IP in the neighbor table + arp_status=$(ip neigh show | grep -w "$ip" | awk '{print $NF}') 2>/dev/null + + # Check if the current IP is reachable + if [ -z "$arp_status" ] || { [ "$arp_status" != "REACHABLE" ] && [ "$arp_status" != "DELAY" ]; }; then + if [ -z "$sigstrength" ]; then + conntime="STALE" + fi + continue + else + # Set the clientip to the current IP if it is reachable or delay + clientip="$ip" + break + fi + done + + # Fallback to using the ARP table if no reachable IP was found + if [ -z "$clientip" ]; then + clientip=$(cat /proc/net/arp | grep "$maclower" | awk '{print $1}' | sort | uniq | tail -n 1) 2>/dev/null + fi + + paddedclientip=$(echo "${clientip}" | grep -o -E '([0-9]*\.|[0-9]*)' | awk '{printf( "%03d\n", $1)}' | tr '\n' '.' | sed 's/.$//') 2>/dev/null + + #calcs + txtotalgb=$(echo $txtotalbytes | awk -v txb=$txtotalbytes 'BEGIN{printf "%0.2f\n", txb/1024/1024/1024}') 2>/dev/null + rxtotalgb=$(echo $rxtotalbytes | awk -v rxb=$rxtotalbytes 'BEGIN{printf "%0.2f\n", rxb/1024/1024/1024}') 2>/dev/null + txratembps=$(echo $txratekbps | awk -v txm=$txratekbps 'BEGIN{printf "%0.1f\n", txm/1000}') 2>/dev/null + rxratembps=$(echo $rxratekbps | awk -v rxm=$rxratekbps 'BEGIN{printf "%0.1f\n", rxm/1000}') 2>/dev/null + + local found=0 + local counter=0 + while [ $counter -le $maxextractcount ] + do + counter=$((counter+1)) + local clientextract="$(echo $clients | cut -d "<" -f$counter | cut -d ">" -f1,2)" + + if [ -z "$clientextract" ]; then + break + fi + + local client="$(echo $clientextract | awk -F ">" '{print $1}')" + local mac="$(echo $clientextract | awk -F ">" '{print $2}')" + + if [ "$mac" == "$clientmac" ]; then + clientname=$client + found=1 + break + fi + done + # Fallback to using dnsmasq.leases if no match found + if [ $found -ne 1 ]; then + clientname=$(echo "$dhcpleases" | grep -i "$lookup_mac" | awk '{print $4}') 2>/dev/null + if [ -z "$clientname" ] || [ "$clientname" == "*" ]; then + clientname="UNKNOWN" + fi + fi + if [ -n "$paddedclientip" ] && [ "$paddedclientip" != "000.000.000.000" ]; then + # Add the check for already processed clients + if grep -qi "$clientmac" /jffs/addons/rtrmon.d/processed_clients.txt; then + # Skip processing if the device was already handled + continue + else + echo "$clientmac" >> /jffs/addons/rtrmon.d/processed_clients.txt + fi + #delete entry from temparp table + sed -i -e '/'$maclower'/d' /jffs/addons/rtrmon.d/temparp.txt + echo "$clientname,$paddedclientip,$clientmac,$conntime,$txtotalgb,$rxtotalgb,$txratembps,$rxratembps,$sigstrength" >> /jffs/addons/rtrmon.d/clientlist$iface.txt + fi + done + + if [ -f "/jffs/addons/rtrmon.d/clientlist$iface.txt" ]; then + if [ $maxclientcount -ge 1 ]; then + sort -f -d -o /jffs/addons/rtrmon.d/clientlist$iface.txt -k "$SortbyNum" -t , /jffs/addons/rtrmon.d/clientlist$iface.txt 2>/dev/null + column -t -s',' -o' | ' -N Name,IP,MAC,Uptime,"TX GB","RX GB","TX Mbps","RX Mbps","Sig" /jffs/addons/rtrmon.d/clientlist$iface.txt | sed 's/^/ /' + else + echo -e " No Devices Connected" + fi + else + echo -e " No Devices Connected" + fi +} + +# ------------------------------------------------------------------------------------------------------------------------- +# attachedguestclients pulls connected client info from wl, arp and nvram +##------------------------------------------## +## Modified by ExtremeFiretop [2024-Aug-06] ## +##------------------------------------------## +attachedguestclients() { + iface="$1" + rm -f /jffs/addons/rtrmon.d/wificlients$iface.txt + wl -i $iface assoclist > /jffs/addons/rtrmon.d/wificlients$iface.txt + maxclientcount=$(cat /jffs/addons/rtrmon.d/wificlients$iface.txt | wc -l) + rm -f /jffs/addons/rtrmon.d/clientlist$iface.txt + dhcpleases="$(read_all_dhcp_leases)" + local clients=$(nvram get custom_clientlist) + local maxextractcount=$(echo "$clients" | awk -F'>>' '{count=0; for (i=1; i<=NF; i++) if ($i != "") count++; print count}') + + local clientcount=0 + while [ $clientcount -le $maxclientcount ] + do + clientname="" + conntime="" + clientip="" + paddedclientip="" + clientcount=$((clientcount+1)) + local clientmac=$(awk 'NR=='$clientcount' {print $2}' /jffs/addons/rtrmon.d/wificlients$iface.txt) + + if [ -z "$clientmac" ]; then + continue + fi + + networktime=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/in network/ {print $3}') 2>/dev/null + conntime=$(date -d@$networktime -u +%Hh:%Mm) 2>/dev/null + txtotalbytes=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/tx total bytes:/ {print $4}') 2>/dev/null + rxtotalbytes=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rx data bytes:/ {print $4}') 2>/dev/null + txratekbps=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rate of last tx pkt:/ {print $6}') 2>/dev/null + rxratekbps=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rate of last rx pkt:/ {print $6}') 2>/dev/null + sigstrength=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/smoothed rssi:/ {print $3}') 2>/dev/null + maclower=$(echo "$clientmac" | awk '{print tolower($0)}') 2>/dev/null + # --- Unified MLD MAC retrieval logic --- + lookup_mac=$(get_lookup_mac "$maclower" "$dhcpleases") + + # Find IPs for the given MAC address in the ARP table + ips=$(grep "$maclower" "/jffs/addons/rtrmon.d/temparp.txt" | awk '{print $1}') 2>/dev/null + + # Iterate over the IPs to find the reachable one + for ip in $ips; do + # Check the status of the IP in the neighbor table + arp_status=$(ip neigh show | grep -w "$ip" | awk '{print $NF}') 2>/dev/null + + # Check if the current IP is reachable + if [ -z "$arp_status" ] || { [ "$arp_status" != "REACHABLE" ] && [ "$arp_status" != "DELAY" ]; }; then + if [ -z "$sigstrength" ]; then + conntime="STALE" + fi + continue + else + # Set the clientip to the current IP if it is reachable or delay + clientip="$ip" + break + fi + done + + # Fallback to using the ARP table or DHCP leases if no reachable IP was found + if [ -z "$clientip" ]; then + # Try to get the last IP from the ARP table + clientip=$(cat /proc/net/arp | grep "$maclower" | awk '{print $1}' | sort | uniq | tail -n 1) 2>/dev/null + fi + + paddedclientip=$(echo "${clientip}" | grep -o -E '([0-9]*\.|[0-9]*)' | awk '{printf( "%03d\n", $1)}' | tr '\n' '.' | sed 's/.$//') 2>/dev/null + + #calcs + txtotalgb=$(echo $txtotalbytes | awk '{printf "%0.2f", $1/1024/1024/1024}') 2>/dev/null + rxtotalgb=$(echo $rxtotalbytes | awk '{printf "%0.2f", $1/1024/1024/1024}') 2>/dev/null + txratembps=$(echo $txratekbps | awk '{printf "%0.1f", $1/1000}') 2>/dev/null + rxratembps=$(echo $rxratekbps | awk '{printf "%0.1f", $1/1000}') 2>/dev/null + + local found=0 + local counter=0 + while [ $counter -le $maxextractcount ] + do + counter=$((counter+1)) + local clientextract="$(echo $clients | cut -d "<" -f$counter | cut -d ">" -f1,2)" + + if [ -z "$clientextract" ]; then + break + fi + + local client=$(echo $clientextract | awk -F ">" '{print $1}') + local mac=$(echo $clientextract | awk -F ">" '{print $2}') + + if [ "$mac" == "$clientmac" ]; then + clientname=$client + found=1 + break + fi + done + # Fallback to using dnsmasq.leases if no match found + if [ $found -ne 1 ]; then + clientname=$(echo "$dhcpleases" | grep -i "$lookup_mac" | awk '{print $4}') 2>/dev/null + if [ -z "$clientname" ] || [ "$clientname" == "*" ]; then + clientname="UNKNOWN" + fi + fi + if [ -n "$paddedclientip" ] && [ "$paddedclientip" != "000.000.000.000" ]; then + # Add the check for already processed clients + if grep -qi "$clientmac" /jffs/addons/rtrmon.d/processed_clients.txt; then + # Skip processing if the device was already handled + continue + else + echo "$clientmac" >> /jffs/addons/rtrmon.d/processed_clients.txt + fi + #delete entry from temparp table + sed -i -e '/'$maclower'/d' /jffs/addons/rtrmon.d/temparp.txt + echo "$clientname,$paddedclientip,$clientmac,$conntime,$txtotalgb,$rxtotalgb,$txratembps,$rxratembps,$sigstrength" >> /jffs/addons/rtrmon.d/clientlist$iface.txt + fi + done + + if [ -f "/jffs/addons/rtrmon.d/clientlist$iface.txt" ]; then + if [ $maxclientcount -ge 1 ]; then + sort -f -d -o /jffs/addons/rtrmon.d/clientlist$iface.txt -k "$SortbyNum" -t , /jffs/addons/rtrmon.d/clientlist$iface.txt 2>/dev/null + column -t -s',' -o' | ' -N Name,IP,MAC,Uptime,"TX GB","RX GB","TX Mbps","RX Mbps","Sig" /jffs/addons/rtrmon.d/clientlist$iface.txt | sed 's/^/ /' + else + echo -e " No Devices Connected" + fi + else + echo -e " No Devices Connected" + fi +} + +# ------------------------------------------------------------------------------------------------------------------------- +# attachedvlanclients pulls connected client info from wl, arp and nvram + +attachedvlanclients() { + iface="$1" + vlansfound=1 + maxclientcount=$(cat /jffs/addons/rtrmon.d/temparpvlan.txt | wc -l) + rm -f /jffs/addons/rtrmon.d/vlanclients$iface.txt + dhcpleases="$(read_all_dhcp_leases)" + local clients=$(nvram get custom_clientlist) + local maxextractcount=$(echo "$clients" | awk -F'>>' '{count=0; for (i=1; i<=NF; i++) if ($i != "") count++; print count}') + + local clientcount=0 + while [ $clientcount -le $maxclientcount ] + do + clientname="" + conntime="" + clientip="" + paddedclientip="" + interface_name="" + clientcount=$((clientcount+1)) + local clientmac=$(awk 'NR=='$clientcount' {print $4}' /jffs/addons/rtrmon.d/temparpvlan.txt | xargs) + + if [ -z "$clientmac" ]; then + continue + fi + + # Convert the MAC address to uppercase and store it in a new variable + macupper=$(echo "$clientmac" | tr 'a-f' 'A-F') + macprefix=$(echo "$macupper" | awk -F ':' '{print $1":"$2":"$3":"$4":"$5}') 2>/dev/null + clientbridgeid=$(awk 'NR=='$clientcount' {print $6}' /jffs/addons/rtrmon.d/temparpvlan.txt | xargs) + if [ -z "$clientbridgeid" ] || [ "$clientbridgeid" != "$iface" ]; then + continue + else + vlansfound=0 + fi + + interfaces=$(ip link show | grep -E 'wl|wlan' | awk -F: '{print $2}' | tr -d ' ') + for wirelessface in $interfaces; do + # Suppress both standard output and error from the wl command and check for the MAC + if wl -i "$wirelessface" assoclist 2>/dev/null | grep -iq "$macprefix"; then + # Save the interface name into the variable + interface_name="$wirelessface" + continue + fi + done + + networktime=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/in network/ {print $3}') 2>/dev/null + # Set conntime to "OFFLINE" if networktime is empty + if [ -z "$networktime" ]; then + conntime="AiMesh" + else + conntime=$(date -d@$networktime -u +%Hh:%Mm) 2>/dev/null + fi + txtotalbytes=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/tx total bytes:/ {print $4}') 2>/dev/null + rxtotalbytes=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/rx data bytes:/ {print $4}') 2>/dev/null + txratekbps=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/rate of last tx pkt:/ {print $6}') 2>/dev/null + rxratekbps=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/rate of last rx pkt:/ {print $6}') 2>/dev/null + sigstrength=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/smoothed rssi:/ {print $3}') 2>/dev/null + + # --- Unified MLD MAC lookup for VLAN clients --- + maclower=$(echo "$clientmac" | awk '{print tolower($0)}') 2>/dev/null + lookup_mac=$(get_lookup_mac "$maclower" "$dhcpleases") + + # Find IPs for the given MAC address in the ARP table + ips=$(grep "$clientmac" "/jffs/addons/rtrmon.d/temparp.txt" | awk '{print $1}') 2>/dev/null + + # Iterate over the IPs to find the reachable one + for ip in $ips; do + # Check the status of the IP in the neighbor table + arp_status=$(ip neigh show | grep -w "$ip" | awk '{print $NF}') 2>/dev/null + + # Check if the current IP is reachable + if [ -z "$arp_status" ] || { [ "$arp_status" != "REACHABLE" ] && [ "$arp_status" != "DELAY" ]; }; then + if [ -z "$sigstrength" ]; then + conntime="STALE" + fi + continue + else + # Set the clientip to the current IP if it is reachable or delay + clientip="$ip" + break + fi + done + + # Fallback to using the ARP table if no reachable IP was found + if [ -z "$clientip" ]; then + clientip=$(cat /proc/net/arp | grep "$clientmac" | awk '{print $1}' | sort | uniq | tail -n 1) 2>/dev/null + fi + + paddedclientip=$(echo "$clientip" | awk -F '.' '{printf "%03d.%03d.%03d.%03d\n", $1, $2, $3, $4}') 2>/dev/null + + #calcs + txtotalgb=$(echo $txtotalbytes | awk '{printf "%0.2f", $1/1024/1024/1024}') 2>/dev/null + rxtotalgb=$(echo $rxtotalbytes | awk '{printf "%0.2f", $1/1024/1024/1024}') 2>/dev/null + txratembps=$(echo $txratekbps | awk '{printf "%0.1f", $1/1000}') 2>/dev/null + rxratembps=$(echo $rxratekbps | awk '{printf "%0.1f", $1/1000}') 2>/dev/null + + local found=0 + local counter=0 + while [ $counter -le $maxextractcount ] + do + counter=$((counter+1)) + local clientextract="$(echo $clients | cut -d "<" -f$counter | cut -d ">" -f1,2)" + + if [ -z "$clientextract" ]; then + break + fi + + local client="$(echo $clientextract | awk -F ">" '{print $1}')" + local mac="$(echo $clientextract | awk -F ">" '{print $2}')" + + if [ "$mac" == "$macupper" ]; then + clientname=$client + found=1 + break + fi + + done + # Fallback to using dnsmasq.leases if no match found + if [ $found -ne 1 ]; then + clientname=$(echo "$dhcpleases" | grep -i "$lookup_mac" | awk '{print $4}') 2>/dev/null + if [ -z "$clientname" ] || [ "$clientname" == "*" ]; then + clientname="UNKNOWN" + fi + fi + if [ -n "$paddedclientip" ] && [ "$paddedclientip" != "000.000.000.000" ]; then + # Check if this MAC address has already been processed + if grep -q "$macupper" /jffs/addons/rtrmon.d/processed_vlanclients.txt && [ "$conntime" = "STALE" ]; then + continue # Skip processing this MAC address + else + # Mark this MAC as processed by adding it to the processed_macs_file + echo "$macupper" >> /jffs/addons/rtrmon.d/processed_vlanclients.txt + fi + #delete entry from temparp table + sed -i -e '/'$clientmac'/d' /jffs/addons/rtrmon.d/temparp.txt + if [ "$conntime" = "AiMesh" ]; then + echo "$clientname,$paddedclientip,$macupper,$conntime" >> /jffs/addons/rtrmon.d/vlanclients$iface.txt + else + echo "$clientname,$paddedclientip,$macupper,$conntime,$txtotalgb,$rxtotalgb,$txratembps,$rxratembps,$sigstrength" >> /jffs/addons/rtrmon.d/vlanclients$iface.txt + fi + fi + done + + if [ -f "/jffs/addons/rtrmon.d/vlanclients$iface.txt" ]; then + if [ $vlansfound -eq 0 ]; then + sort -f -d -t ',' -k "$SortbyNum" -k 4,4 /jffs/addons/rtrmon.d/vlanclients$iface.txt 2>/dev/null | \ + awk -F',' -v OFS=',' '{if ($4 ~ /AiMesh/) {a[i++]=$0} else {print $0}} END {for (j=0; j /tmp/vlanclients_sorted.txt + # Move sorted file back to original + mv /tmp/vlanclients_sorted.txt /jffs/addons/rtrmon.d/vlanclients$iface.txt + column -t -s',' -o' | ' -N Name,IP,MAC,Uptime,"TX GB","RX GB","TX Mbps","RX Mbps","Sig" /jffs/addons/rtrmon.d/vlanclients$iface.txt | sed 's/^/ /' + else + echo -e " No Devices Connected" + fi + else + echo -e " No Devices Connected" + fi +} + +# ------------------------------------------------------------------------------------------------------------------------- +# attachedlanclients pulls connected client info from wl, arp and nvram + +attachedlanclients () +{ + maxclientcount=$(cat /jffs/addons/rtrmon.d/temparp.txt | wc -l) + rm -f /jffs/addons/rtrmon.d/clientlistbr0.txt + dhcpleases="$(read_all_dhcp_leases)" + #find matchine client name + local clients=$(nvram get custom_clientlist) + local maxextractcount=$(echo "$clients" | awk -F'>>' '{count=0; for (i=1; i<=NF; i++) if ($i != "") count++; print count}') + + local clientcount=0 + while [ $clientcount -le $maxclientcount ] + do + clientname="" + paddedclientip="" + clientcount=$((clientcount+1)) + local clientmac=$(cat /jffs/addons/rtrmon.d/temparp.txt | awk 'NR=='$clientcount' {print $4}') 2>/dev/null + + if [ -z "$clientmac" ]; then + continue + fi + + local macupper=$(echo "$clientmac" | tr 'a-f' 'A-F') + + # Add the check for already processed clients + if grep -qi "$clients" /jffs/addons/rtrmon.d/processed_clients.txt; then + # Skip processing if the device was already handled + continue + else + echo "$macupper" >> /jffs/addons/rtrmon.d/processed_clients.txt + fi + + local counter=0 + local found=0 + while [ $counter -le $maxextractcount ] + do + counter=$((counter+1)) + local clientextract="$(echo $clients | cut -d "<" -f$counter | cut -d ">" -f1,2)" + + if [ -z "$clientextract" ]; then + continue + fi + + #clientip=$(cat /proc/net/arp | grep $clientmac | awk '{print $1}') + clientip=$(cat /jffs/addons/rtrmon.d/temparp.txt | grep $clientmac | awk '{print $1; exit}') 2>/dev/null + paddedclientip=$(echo "${clientip}" | grep -o -E '([0-9]*\.|[0-9]*)' | awk '{printf( "%03d\n", $1)}' | tr '\n' '.' | sed 's/.$//') 2>/dev/null + if [ -z $paddedclientip ]; then paddedclientip="000.000.000.000"; fi + + local client="$(echo $clientextract | awk -F ">" '{print $1}')" + local mac="$(echo $clientextract | awk -F ">" '{print $2}')" + + if [ "$mac" == "$macupper" ]; then + clientname=$client + found=1 + break + fi + done + # Fallback to using dnsmasq.leases if no match found + if [ $found -ne 1 ]; then + clientname=$(echo "$dhcpleases" | grep -i "$clientmac" | awk '{print $4}') + if [ -z "$clientname" ] || [ "$clientname" == "*" ]; then + clientname="UNKNOWN" + fi + fi + if [ -n "$paddedclientip" ] && [ "$paddedclientip" != "000.000.000.000" ]; then + echo "$clientname,$paddedclientip,$macupper" >> /jffs/addons/rtrmon.d/clientlistbr0.txt + fi + done + + if [ -f "/jffs/addons/rtrmon.d/clientlistbr0.txt" ]; then + if [ $maxclientcount -ge 1 ]; then + sort -f -d -o /jffs/addons/rtrmon.d/clientlistbr0.txt -k "$SortbyNum" -t , /jffs/addons/rtrmon.d/clientlistbr0.txt 2>/dev/null + column -t -s',' -o' | ' -N Name,IP,MAC /jffs/addons/rtrmon.d/clientlistbr0.txt | sed 's/^/ /' + else + echo -e " No Devices Connected" + fi + else + echo -e " No Devices Connected" + fi +} + +# ------------------------------------------------------------------------------------------------------------------------- +# GetVPNWGIPCITY is a function that gathers IP/City stats from all active VPN and WG connections + +GetVPNWGIPCITY() +{ + + vpn1slot=1 + VPN1State="$(_VPN_GetClientState_ ${vpn1slot})" + if [ -z "$VPN1State" ]; then VPN1State=0; fi # to catch possible wireguard interference + if [ "$VPN1State" -eq 2 ]; then + if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing VPN1 Stats...]"; fi + TUN1="tun1"$vpn1slot + NVRAMVPN1ADDR=$($timeoutcmd$timeoutsec nvram get vpn_client"$vpn1slot"_addr) + NVRAMVPN1IP=$(ping -c 1 -w 1 $NVRAMVPN1ADDR | awk -F '[()]' '/PING/ { print $2}') + + if [ "$NVRAMVPN1ADDR" != "$oldvpn1ADDR" ]; then + oldvpn1ip=$(curl --silent --fail --interface $TUN1 --request GET --url https://ipv4.icanhazip.com) + if [ -z $oldvpn1ip ]; then oldvpn1ip=$NVRAMVPN1IP; fi + oldvpn1ADDR=$NVRAMVPN1ADDR + fi + + if [ "$(echo $NVRAMVPN1IP | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then + oldvpn1ip=$NVRAMVPN1IP + oldvpn1city="Private Network" + elif [ "$vpn1ip" != "$oldvpn1ip" ]; then + oldvpn1city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldvpn1ip | jq --raw-output .city" + oldvpn1city="$(eval $oldvpn1city)"; if echo $oldvpn1city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldvpn1city="Undetermined"; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: API call made to determine geolocation of VPN$vpn1slot: $oldvpn1ip ($oldvpn1city)" >> $LOGFILE + fi + + vpn1ip=$oldvpn1ip + vpn1city=$oldvpn1city + vpn1on="True" + + else + vpn1on="False" + fi + + #Check to see if there's a secondary VPN connection + vpn2slot=2 + VPN2State="$(_VPN_GetClientState_ ${vpn2slot})" + if [ -z "$VPN2State" ]; then VPN2State=0; fi # to catch possible wireguard interference + if [ "$VPN2State" -eq 2 ]; then + if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing VPN2 Stats...]"; fi + TUN2="tun1"$vpn2slot + NVRAMVPN2ADDR=$($timeoutcmd$timeoutsec nvram get vpn_client"$vpn2slot"_addr) + NVRAMVPN2IP=$(ping -c 1 -w 1 $NVRAMVPN2ADDR | awk -F '[()]' '/PING/ { print $2}') + + if [ "$NVRAMVPN2ADDR" != "$oldvpn2ADDR" ]; then + oldvpn2ip=$(curl --silent --fail --interface $TUN2 --request GET --url https://ipv4.icanhazip.com) + if [ -z $oldvpn2ip ]; then oldvpn2ip=$NVRAMVPN2IP; fi + oldvpn2ADDR=$NVRAMVPN2ADDR + fi + + if [ "$(echo $NVRAMVPN2IP | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then + oldvpn2ip=$NVRAMVPN2IP + oldvpn2city="Private Network" + elif [ "$vpn2ip" != "$oldvpn2ip" ]; then + oldvpn2city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldvpn2ip | jq --raw-output .city" + oldvpn2city="$(eval $oldvpn2city)"; if echo $oldvpn2city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldvpn2city="Undetermined"; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: API call made to determine geolocation of VPN$vpn2slot: $oldvpn2ip ($oldvpn2city)" >> $LOGFILE + fi + + vpn2ip=$oldvpn2ip + vpn2city=$oldvpn2city + vpn2on="True" + + else + vpn5on="False" + fi + + #Check to see if there's a third VPN connection + vpn3slot=3 + VPN3State="$(_VPN_GetClientState_ ${vpn3slot})" + if [ -z "$VPN3State" ]; then VPN3State=0; fi # to catch possible wireguard interference + if [ "$VPN3State" -eq 2 ]; then + if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing VPN3 Stats...]"; fi + TUN3="tun1"$vpn3slot + NVRAMVPN3ADDR=$($timeoutcmd$timeoutsec nvram get vpn_client"$vpn3slot"_addr) + NVRAMVPN3IP=$(ping -c 1 -w 1 $NVRAMVPN3ADDR | awk -F '[()]' '/PING/ { print $2}') + + if [ "$NVRAMVPN3ADDR" != "$oldvpn3ADDR" ]; then + oldvpn3ip=$(curl --silent --fail --interface $TUN3 --request GET --url https://ipv4.icanhazip.com) + if [ -z $oldvpn3ip ]; then oldvpn3ip=$NVRAMVPN3IP; fi + oldvpn3ADDR=$NVRAMVPN3ADDR + fi + + if [ "$(echo $NVRAMVPN3IP | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then + oldvpn3ip=$NVRAMVPN3IP + oldvpn3city="Private Network" + elif [ "$vpn3ip" != "$oldvpn3ip" ]; then + oldvpn3city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldvpn3ip | jq --raw-output .city" + oldvpn3city="$(eval $oldvpn3city)"; if echo $oldvpn3city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldvpn3city="Undetermined"; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: API call made to determine geolocation of VPN$vpn3slot: $oldvpn3ip ($oldvpn3city)" >> $LOGFILE + fi + + vpn3ip=$oldvpn3ip + vpn3city=$oldvpn3city + vpn3on="True" + + else + vpn3on="False" + fi + + #Check to see if there's a fourth VPN connection + vpn4slot=4 + VPN4State="$(_VPN_GetClientState_ ${vpn4slot})" + if [ -z "$VPN4State" ]; then VPN4State=0; fi # to catch possible wireguard interference + if [ "$VPN4State" -eq 2 ]; then + if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing VPN4 Stats...]"; fi + TUN4="tun1"$vpn4slot + NVRAMVPN4ADDR=$($timeoutcmd$timeoutsec nvram get vpn_client"$vpn4slot"_addr) + NVRAMVPN4IP=$(ping -c 1 -w 1 $NVRAMVPN4ADDR | awk -F '[()]' '/PING/ { print $2}') + + if [ "$NVRAMVPN4ADDR" != "$oldvpn4ADDR" ]; then + oldvpn4ip=$(curl --silent --fail --interface $TUN4 --request GET --url https://ipv4.icanhazip.com) + if [ -z $oldvpn4ip ]; then oldvpn4ip=$NVRAMVPN4IP; fi + oldvpn4ADDR=$NVRAMVPN4ADDR + fi + + if [ "$(echo $NVRAMVPN4IP | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then + oldvpn4ip=$NVRAMVPN4IP + oldvpn4city="Private Network" + elif [ "$vpn4ip" != "$oldvpn4ip" ]; then + oldvpn4city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldvpn4ip | jq --raw-output .city" + oldvpn4city="$(eval $oldvpn4city)"; if echo $oldvpn4city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldvpn4city="Undetermined"; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: API call made to determine geolocation of VPN$vpn4slot: $oldvpn4ip ($oldvpn4city)" >> $LOGFILE + fi + + vpn4ip=$oldvpn4ip + vpn4city=$oldvpn4city + vpn4on="True" + + else + vpn4on="False" + fi + + #Check to see if there's a fifth VPN connection + vpn5slot=5 + VPN5State="$(_VPN_GetClientState_ ${vpn5slot})" + if [ -z "$VPN5State" ]; then VPN5State=0; fi # to catch possible wireguard interference + if [ "$VPN5State" -eq 2 ]; then + if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing VPN5 Stats...]"; fi + TUN5="tun1"$vpn5slot + NVRAMVPN5ADDR=$($timeoutcmd$timeoutsec nvram get vpn_client"$vpn5slot"_addr) + NVRAMVPN5IP=$(ping -c 1 -w 1 $NVRAMVPN5ADDR | awk -F '[()]' '/PING/ { print $2}') + + if [ "$NVRAMVPN5ADDR" != "$oldvpn5ADDR" ]; then + oldvpn5ip=$(curl --silent --fail --interface $TUN5 --request GET --url https://ipv4.icanhazip.com) + if [ -z $oldvpn5ip ]; then oldvpn5ip=$NVRAMVPN5IP; fi + oldvpn5ADDR=$NVRAMVPN5ADDR + fi + + if [ "$(echo $NVRAMVPN5IP | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then + oldvpn5ip=$NVRAMVPN5IP + oldvpn5city="Private Network" + elif [ "$vpn5ip" != "$oldvpn5ip" ]; then + oldvpn5city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldvpn5ip | jq --raw-output .city" + oldvpn5city="$(eval $oldvpn5city)"; if echo $oldvpn5city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldvpn5city="Undetermined"; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: API call made to determine geolocation of VPN$vpn5slot: $oldvpn5ip ($oldvpn5city)" >> $LOGFILE + fi + + vpn5ip=$oldvpn5ip + vpn5city=$oldvpn5city + vpn5on="True" + + else + vpn5on="False" + fi + + #Check to see if there's a WGC1 connection + wg1slot=1 + WG1State="$(_WG_GetClientState_ ${wg1slot})" + if [ -z "$WG1State" ]; then WG1State=0; fi + if [ "$WG1State" -eq 2 ]; then + WGTUN1="wgc$wg1slot" + WGTUN1_IP=$($timeoutcmd$timeoutsec nvram get "$WGTUN1"_addr | cut -d '/' -f1) + WG1ADDR=$($timeoutcmd$timeoutsec nvram get "$WGTUN1"_ep_addr) + NVRAMWG1IP=$(ping -c 1 -w 1 $WGTUN1_IP | awk -F '[()]' '/PING/ { print $2}') + if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing WG1 Stats...]"; fi + if [ "$WG1ADDR" != "$oldwg1ADDR" ] || [ "$wg1ip" = "0.0.0.0" ]; then + # Added based on suggestion from @ZebMcKayhan + ip rule add from $WGTUN1_IP lookup $WGTUN1 prio 10 >/dev/null 2>&1 + oldwg1ip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN1" --request GET --url https://ipv4.icanhazip.com" + oldwg1ip="$(eval $oldwg1ip)" + if [ -z "$oldwg1ip" ] || echo "$oldwg1ip" | grep -qoE 'Internet|traffic|Error|error' + then + oldwg1ip="$NVRAMWG1IP" + fi + oldwg1ADDR=$WG1ADDR + # Added based on suggestion from @ZebMcKayhan + ip rule del prio 10 >/dev/null 2>&1 + fi + + if [ "$(echo "$oldwg1ip" | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then + oldwg1ip="$NVRAMWG1IP" + oldwg1city="Private Network" + elif [ "$wg1ip" != "$oldwg1ip" ]; then + oldwg1city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldwg1ip | jq --raw-output .city" + oldwg1city="$(eval $oldwg1city)"; if echo $oldwg1city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldwg1city="Undetermined"; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - API call made to determine geolocation of WG$wg1slot: $oldwg1ip ($oldwg1city)" >> $LOGFILE + fi + + wg1ip="$oldwg1ip" + wg1city="$oldwg1city" + wg1on="True" + + else + wg1on="False" + fi + + #Check to see if there's a WGC2 connection + wg2slot=2 + WG2State="$(_WG_GetClientState_ ${wg2slot})" + if [ -z "$WG2State" ]; then WG2State=0; fi + if [ "$WG2State" -eq 2 ]; then + WGTUN2="wgc$wg2slot" + WGTUN2_IP=$($timeoutcmd$timeoutsec nvram get "$WGTUN2"_addr | cut -d '/' -f1) + WG2ADDR=$($timeoutcmd$timeoutsec nvram get "$WGTUN2"_ep_addr) + NVRAMWG2IP=$(ping -c 1 -w 1 $WGTUN2_IP | awk -F '[()]' '/PING/ { print $2}') + if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing WG2 Stats...]"; fi + if [ "$WG2ADDR" != "$oldwg2ADDR" ] || [ "$wg2ip" = "0.0.0.0" ]; then + # Added based on suggestion from @ZebMcKayhan + ip rule add from $WGTUN2_IP lookup $WGTUN2 prio 10 >/dev/null 2>&1 + oldwg2ip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN2" --request GET --url https://ipv4.icanhazip.com" + oldwg2ip="$(eval $oldwg2ip)" + if [ -z "$oldwg2ip" ] || echo "$oldwg2ip" | grep -qoE 'Internet|traffic|Error|error' + then + oldwg2ip="$NVRAMWG2IP" + fi + oldwg2ADDR=$WG2ADDR + # Added based on suggestion from @ZebMcKayhan + ip rule del prio 10 >/dev/null 2>&1 + fi + + if [ "$(echo "$oldwg2ip" | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then + oldwg2ip="$NVRAMWG2IP" + oldwg2city="Private Network" + elif [ "$wg2ip" != "$oldwg2ip" ]; then + oldwg2city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldwg2ip | jq --raw-output .city" + oldwg2city="$(eval $oldwg2city)"; if echo $oldwg2city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldwg2city="Undetermined"; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - API call made to determine geolocation of WG$wg2slot: $oldwg2ip ($oldwg2city)" >> $LOGFILE + fi + + wg2ip="$oldwg2ip" + wg2city="$oldwg2city" + wg2on="True" + + else + wg2on="False" + fi + + #Check to see if there's a WGC3 connection + wg3slot=3 + WG3State="$(_WG_GetClientState_ ${wg3slot})" + if [ -z "$WG3State" ]; then WG3State=0; fi + if [ "$WG3State" -eq 2 ]; then + WGTUN3="wgc$wg3slot" + WGTUN3_IP=$($timeoutcmd$timeoutsec nvram get "$WGTUN3"_addr | cut -d '/' -f1) + WG3ADDR=$($timeoutcmd$timeoutsec nvram get "$WGTUN3"_ep_addr) + NVRAMWG3IP=$(ping -c 1 -w 1 $WGTUN3_IP | awk -F '[()]' '/PING/ { print $2}') + if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing WG3 Stats...]"; fi + if [ "$WG3ADDR" != "$oldwg3ADDR" ] || [ "$wg3ip" = "0.0.0.0" ]; then + # Added based on suggestion from @ZebMcKayhan + ip rule add from $WGTUN3_IP lookup $WGTUN3 prio 10 >/dev/null 2>&1 + oldwg3ip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN3" --request GET --url https://ipv4.icanhazip.com" + oldwg3ip="$(eval $oldwg3ip)" + if [ -z "$oldwg3ip" ] || echo "$oldwg3ip" | grep -qoE 'Internet|traffic|Error|error' + then + oldwg3ip="$NVRAMWG3IP" + fi + oldwg3ADDR=$WG3ADDR + # Added based on suggestion from @ZebMcKayhan + ip rule del prio 10 >/dev/null 2>&1 + fi + + if [ "$(echo "$oldwg3ip" | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then + oldwg3ip="$NVRAMWG3IP" + oldwg3city="Private Network" + elif [ "$wg3ip" != "$oldwg3ip" ]; then + oldwg3city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldwg3ip | jq --raw-output .city" + oldwg3city="$(eval $oldwg3city)"; if echo $oldwg3city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldwg3city="Undetermined"; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - API call made to determine geolocation of WG$wg3slot: $oldwg3ip ($oldwg3city)" >> $LOGFILE + fi + + wg3ip="$oldwg3ip" + wg3city="$oldwg3city" + wg3on="True" + + else + wg3on="False" + fi + + #Check to see if there's a WGC4 connection + wg4slot=4 + WG14State="$(_WG_GetClientState_ ${wg4slot})" + if [ -z "$WG4State" ]; then WG4State=0; fi + if [ "$WG4State" -eq 2 ]; then + WGTUN4="wgc$wg4slot" + WGTUN4_IP=$($timeoutcmd$timeoutsec nvram get "$WGTUN4"_addr | cut -d '/' -f1) + WG4ADDR=$($timeoutcmd$timeoutsec nvram get "$WGTUN4"_ep_addr) + NVRAMWG4IP=$(ping -c 1 -w 1 $WGTUN4_IP | awk -F '[()]' '/PING/ { print $2}') + if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing WG4 Stats...]"; fi + if [ "$WG4ADDR" != "$oldwg4ADDR" ] || [ "$wg4ip" = "0.0.0.0" ]; then + # Added based on suggestion from @ZebMcKayhan + ip rule add from $WGTUN4_IP lookup $WGTUN4 prio 10 >/dev/null 2>&1 + oldwg4ip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN4" --request GET --url https://ipv4.icanhazip.com" + oldwg4ip="$(eval $oldwg4ip)" + if [ -z "$oldwg4ip" ] || echo "$oldwg4ip" | grep -qoE 'Internet|traffic|Error|error' + then + oldwg4ip="$NVRAMWG4IP" + fi + oldwg4ADDR=$WG4ADDR + # Added based on suggestion from @ZebMcKayhan + ip rule del prio 10 >/dev/null 2>&1 + fi + + if [ "$(echo "$oldwg4ip" | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then + oldwg4ip="$NVRAMWG4IP" + oldwg4city="Private Network" + elif [ "$wg4ip" != "$oldwg4ip" ]; then + oldwg4city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldwg4ip | jq --raw-output .city" + oldwg4city="$(eval $oldwg4city)"; if echo $oldwg1city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldwg4city="Undetermined"; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - API call made to determine geolocation of WG$wg4slot: $oldwg4ip ($oldwg4city)" >> $LOGFILE + fi + + wg4ip="$oldwg4ip" + wg4city="$oldwg4city" + wg4on="True" + + else + wg4on="False" + fi + + #Check to see if there's a WGC5 connection + wg5slot=5 + WG5State="$(_WG_GetClientState_ ${wg5slot})" + if [ -z "$WG5State" ]; then WG5State=0; fi + if [ "$WG5State" -eq 2 ]; then + WGTUN5="wgc$wg5slot" + WGTUN5_IP=$($timeoutcmd$timeoutsec nvram get "$WGTUN5"_addr | cut -d '/' -f1) + WG5ADDR=$($timeoutcmd$timeoutsec nvram get "$WGTUN5"_ep_addr) + NVRAMWG5IP=$(ping -c 1 -w 1 $WGTUN5_IP | awk -F '[()]' '/PING/ { print $2}') + if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing WG5 Stats...]"; fi + if [ "$WG5ADDR" != "$oldwg5ADDR" ] || [ "$wg5ip" = "0.0.0.0" ]; then + # Added based on suggestion from @ZebMcKayhan + ip rule add from $WGTUN5_IP lookup $WGTUN5 prio 10 >/dev/null 2>&1 + oldwg5ip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN5" --request GET --url https://ipv4.icanhazip.com" + oldwg5ip="$(eval $oldwg5ip)" + if [ -z "$oldwg5ip" ] || echo "$oldwg5ip" | grep -qoE 'Internet|traffic|Error|error' + then + oldwg5ip="$NVRAMWG5IP" + fi + oldwg5ADDR=$WG5ADDR + # Added based on suggestion from @ZebMcKayhan + ip rule del prio 10 >/dev/null 2>&1 + fi + + if [ "$(echo "$oldwg5ip" | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then + oldwg5ip="$NVRAMWG5IP" + oldwg5city="Private Network" + elif [ "$wg5ip" != "$oldwg5ip" ]; then + oldwg5city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldwg5ip | jq --raw-output .city" + oldwg5city="$(eval $oldwg5city)"; if echo $oldwg5city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldwg5city="Undetermined"; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - API call made to determine geolocation of WG$wg5slot: $oldwg5ip ($oldwg5city)" >> $LOGFILE + fi + + wg5ip="$oldwg5ip" + wg5city="$oldwg5city" + wg5on="True" + + else + wg5on="False" + fi + +} + +# ------------------------------------------------------------------------------------------------------------------------- +# GetVPNWGStats is a function that calculates connection stats from all active VPN and WG connections + +GetVPNWGStats() +{ + + if [ "$vpn1on" == "True" ]; then + oldvpntxrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn1slot/status 2>/dev/null) + oldvpnrxbytes="$(echo $oldvpntxrxbytes | cut -d' ' -f1)" + oldvpntxbytes="$(echo $oldvpntxrxbytes | cut -d' ' -f2)" + if [ -z $oldvpnrxbytes ]; then oldvpnrxbytes=0; fi + if [ -z $oldvpntxbytes ]; then oldvpntxbytes=0; fi + + if [ $oldvpnrxbytes -le 0 ]; then + oldvpnrxbytes=0 + elif [ $oldvpntxbytes -le 0 ]; then + oldvpntxbytes=0 + fi + fi + + if [ "$vpn2on" == "True" ]; then + oldvpn2txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn2slot/status 2>/dev/null) + oldvpn2rxbytes="$(echo $oldvpn2txrxbytes | cut -d' ' -f1)" + oldvpn2txbytes="$(echo $oldvpn2txrxbytes | cut -d' ' -f2)" + if [ -z $oldvpn2rxbytes ]; then oldvpn2rxbytes=0; fi + if [ -z $oldvpn2txbytes ]; then oldvpn2txbytes=0; fi + + if [ $oldvpn2rxbytes -le 0 ]; then + oldvpn2rxbytes=0 + elif [ $oldvpn2txbytes -le 0 ]; then + oldvpn2txbytes=0 + fi + fi + + if [ "$vpn3on" == "True" ]; then + oldvpn3txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn3slot/status 2>/dev/null) + oldvpn3rxbytes="$(echo $oldvpn3txrxbytes | cut -d' ' -f1)" + oldvpn3txbytes="$(echo $oldvpn3txrxbytes | cut -d' ' -f2)" + if [ -z $oldvpn3rxbytes ]; then oldvpn3rxbytes=0; fi + if [ -z $oldvpn3txbytes ]; then oldvpn3txbytes=0; fi + + if [ $oldvpn3rxbytes -le 0 ]; then + oldvpn3rxbytes=0 + elif [ $oldvpn3txbytes -le 0 ]; then + oldvpn3txbytes=0 + fi + fi + + if [ "$vpn4on" == "True" ]; then + oldvpn4txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn4slot/status 2>/dev/null) + oldvpn4rxbytes="$(echo $oldvpn4txrxbytes | cut -d' ' -f1)" + oldvpn4txbytes="$(echo $oldvpn4txrxbytes | cut -d' ' -f2)" + if [ -z $oldvpn4rxbytes ]; then oldvpn4rxbytes=0; fi + if [ -z $oldvpn4txbytes ]; then oldvpn4txbytes=0; fi + + if [ $oldvpn4rxbytes -le 0 ]; then + oldvpn4rxbytes=0 + elif [ $oldvpn4txbytes -le 0 ]; then + oldvpn4txbytes=0 + fi + fi + + if [ "$vpn5on" == "True" ]; then + oldvpn5txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn5slot/status 2>/dev/null) + oldvpn5rxbytes="$(echo $oldvpn5txrxbytes | cut -d' ' -f1)" + oldvpn5txbytes="$(echo $oldvpn5txrxbytes | cut -d' ' -f2)" + if [ -z $oldvpn5rxbytes ]; then oldvpn5rxbytes=0; fi + if [ -z $oldvpn5txbytes ]; then oldvpn5txbytes=0; fi + + if [ $oldvpn5rxbytes -le 0 ]; then + oldvpn5rxbytes=0 + elif [ $oldvpn5txbytes -le 0 ]; then + oldvpn5txbytes=0 + fi + fi + + # Check the wireguard connections + if [ "$wg1on" == "True" ]; then + oldwg1txrxbytes=$(wg show wgc1 transfer) + oldwg1rxbytes="$(echo $oldwg1txrxbytes | cut -d' ' -f3)" + oldwg1txbytes="$(echo $oldwg1txrxbytes | cut -d' ' -f2)" + if [ -z $oldwg1rxbytes ] || [ $oldwg1rxbytes -le 0 ]; then oldwg1rxbytes=0; fi + if [ -z $oldwg1txbytes ] || [ $oldwg1txbytes -le 0 ]; then oldwg1txbytes=0; fi + fi + + if [ "$wg2on" == "True" ]; then + oldwg2txrxbytes=$(wg show wgc2 transfer) + oldwg2rxbytes="$(echo $oldwg2txrxbytes | cut -d' ' -f3)" + oldwg2txbytes="$(echo $oldwg2txrxbytes | cut -d' ' -f2)" + if [ -z $oldwg2rxbytes ] || [ $oldwg2rxbytes -le 0 ]; then oldwg2rxbytes=0; fi + if [ -z $oldwg2txbytes ] || [ $oldwg2txbytes -le 0 ]; then oldwg2txbytes=0; fi + fi + + if [ "$wg3on" == "True" ]; then + oldwg3txrxbytes=$(wg show wgc3 transfer) + oldwg3rxbytes="$(echo $oldwg3txrxbytes | cut -d' ' -f3)" + oldwg3txbytes="$(echo $oldwg3txrxbytes | cut -d' ' -f2)" + if [ -z $oldwg3rxbytes ] || [ $oldwg3rxbytes -le 0 ]; then oldwg3rxbytes=0; fi + if [ -z $oldwg3txbytes ] || [ $oldwg3txbytes -le 0 ]; then oldwg3txbytes=0; fi + fi + + if [ "$wg4on" == "True" ]; then + oldwg4txrxbytes=$(wg show wgc4 transfer) + oldwg4rxbytes="$(echo $oldwg4txrxbytes | cut -d' ' -f3)" + oldwg4txbytes="$(echo $oldwg4txrxbytes | cut -d' ' -f2)" + if [ -z $oldwg4rxbytes ] || [ $oldwg4rxbytes -le 0 ]; then oldwg4rxbytes=0; fi + if [ -z $oldwg4txbytes ] || [ $oldwg4txbytes -le 0 ]; then oldwg4txbytes=0; fi + fi + + if [ "$wg5on" == "True" ]; then + oldwg5txrxbytes=$(wg show wgc5 transfer) + oldwg5rxbytes="$(echo $oldwg5txrxbytes | cut -d' ' -f3)" + oldwg5txbytes="$(echo $oldwg5txrxbytes | cut -d' ' -f2)" + if [ -z $oldwg5rxbytes ] || [ $oldwg5rxbytes -le 0 ]; then oldwg5rxbytes=0; fi + if [ -z $oldwg5txbytes ] || [ $oldwg5txbytes -le 0 ]; then oldwg5txbytes=0; fi + fi + +} + +# ------------------------------------------------------------------------------------------------------------------------- +# VPN_GetClientState was created by @Martinski in many thanks to trying to eliminate unknown operand errors due to null +# vpn_clientX_state values + +_VPN_GetClientState_() +{ + if [ $# -lt 1 ] || [ -z "$1" ] || ! echo "$1" | grep -qE "^[1-5]$" + then echo "**ERROR**" ; return 1 ; fi + + local nvramVal="$($timeoutcmd$timeoutsec nvram get "vpn_client${1}_state")" + if [ -z "$nvramVal" ] || ! echo "$nvramVal" | grep -qE "^[0-9]$" + then echo "0" ; else echo "$nvramVal" ; fi + return 0 +} + +# ------------------------------------------------------------------------------------------------------------------------- +# WG_GetClientState is based off _VPN_GetClientState_ + +_WG_GetClientState_() +{ + if [ $# -lt 1 ] || [ -z "$1" ] || ! echo "$1" | grep -qE "^[1-5]$" + then echo "**ERROR**" ; return 1 ; fi + + # Inspiration from ZebMcKayHan's WGC Watchdog Script + last_handshake=$(wg show wgc$1 latest-handshakes | awk '{print $2}') >/dev/null 2>&1 + + if [ -z $last_handshake ] + then + WGnvramVal=0 #disconnected + else + WGnvramVal=2 #connected + fi + + #local WGnvramVal="$($timeoutcmd$timeoutsec nvram get "wgc${1}_enable")" + if [ -z "$WGnvramVal" ] || ! echo "$WGnvramVal" | grep -qE "^[+-]?[0-9]$" + then echo "0" ; else echo "$WGnvramVal" ; fi + return 0 +} + +##-------------------------------------## +## Added by Martinski W. [2024-Nov-02] ## +##-------------------------------------## +_SetUpTimeoutCmdVars_() +{ + # If the timeout utility is available then use it # + if [ -z "${timeoutcmd:+xSETx}" ] && [ -f "/opt/bin/timeout" ] + then + timeoutcmd="timeout " + timeoutsec="10" + timeoutlng="60" + fi +} + +##-------------------------------------## +## Added by Martinski W. [2024-Nov-02] ## +##-------------------------------------## +_SetLAN_HostName_() +{ + [ -z "${LAN_HostName:+xSETx}" ] && \ + LAN_HostName="$($timeoutcmd$timeoutsec nvram get lan_hostname)" +} + +_GetLAN_HostName_() +{ _SetLAN_HostName_ ; echo "$LAN_HostName" ; } + +trap '_IgnoreKeypresses_ OFF ; exit 0' EXIT INT QUIT ABRT TERM + +# ------------------------------------------------------------------------------------------------------------------------- +# Begin Commandline Argument Gatekeeper and Configuration Utility Functionality +# ------------------------------------------------------------------------------------------------------------------------- +##----------------------------------------## +## Modified by Martinski W. [2024-Nov-02] ## +##----------------------------------------## + +DEBUG=; set -x # uncomment/comment to enable/disable debug mode +{ # uncomment/comment to enable/disable debug mode + + _SetUpTimeoutCmdVars_ + _SetLAN_HostName_ + + # Create the necessary folder/file structure for RTRMON under /jffs/addons + if [ ! -d "/jffs/addons/rtrmon.d" ]; then + mkdir -p "/jffs/addons/rtrmon.d" + fi + + # Check for Updates + updatecheck + + RouterModel="$($timeoutcmd$timeoutsec nvram get odmpid)" + [ -z "$RouterModel" ] && RouterModel="$($timeoutcmd$timeoutsec nvram get productid)" + + FWVER="$($timeoutcmd$timeoutsec nvram get firmver | tr -d '.')" + BUILDNO="$($timeoutcmd$timeoutsec nvram get buildno)" + EXTENDNO="$($timeoutcmd$timeoutsec nvram get extendno)" + if [ -z "$EXTENDNO" ]; then EXTENDNO=0; fi + FWBUILD="${FWVER}.${BUILDNO}_${EXTENDNO}" + + # Check for advanced router Features + FourBandCustom55624="False" + FourBandCustom56624="False" + ThreeBand2456="False" + ThreeBand2455="False" + + if [ "$RouterModel" = "GT-AXE16000" ] || [ "$RouterModel" = "GT-BE98" ]; then + FourBandCustom55624="True" + fi + if [ "$RouterModel" = "GT-BE98_Pro" ]; then + FourBandCustom56624="True" + fi + if [ "$RouterModel" = "GT-AXE11000" ] || [ "$RouterModel" = "ZenWiFi_ET8" ] || [ "$RouterModel" = "RT-BE96U" ] || [ "$RouterModel" = "RT-BE92U" ]; then + ThreeBand2456="True" + fi + if [ "$RouterModel" = "GT-AX11000_Pro" ] || [ "$RouterModel" = "GT-AX11000" ] || [ "$RouterModel" = "ZenWiFi_Pro_XT12" ] || [ "$RouterModel" = "ZenWiFi_XT8" ]; then + ThreeBand2455="True" + fi + + # Check what mode the router is in: 1=Router, 2=AP, 3=iMesh Node # + OpsMode="$($timeoutcmd$timeoutsec nvram get sw_mode)" + #OpsMode=3 + + # Check and see if any commandline option is being used + if [ $# -eq 0 ] || [ -z "$1" ] + then + clear + echo "" + echo "RTRMON v$Version" + echo "" + echo "Exiting due to missing commandline options!" + echo "(run 'rtrmon.sh -h' for help)" + echo "" + echo -e "${CClear}" + exit 0 + fi + + # Check and see if an invalid commandline option is being used + if [ "$1" = "-h" ] || [ "$1" = "-help" ] || [ "$1" = "-config" ] || [ "$1" = "-setup" ] || \ + [ "$1" = "-monitor" ] || [ "$1" = "-reset" ] || [ "$1" = "-update" ] || \ + [ "$1" = "-screen" ] || [ "$1" = "-uninstall" ] || [ "$1" = "-log" ] || \ + { [ $# -gt 1 ] && [ "$2" = "-now" ] ; } || { [ $# -gt 2 ] &&[ "$3" = "-now" ] ; } + then + clear + else + clear + echo "" + echo "RTRMON v$Version" + echo "" + echo "Exiting due to invalid commandline options!" + echo "(run 'rtrmon.sh -h' for help)" + echo "" + echo -e "${CClear}" + exit 0 + fi + + # Check to see if the help option is being called + if [ "$1" == "-h" ] || [ "$1" == "-help" ] + then + clear + echo "" + echo "RTRMON v$Version Commandline Option Usage:" + echo "" + echo "rtrmon.sh -h | -help" + echo "rtrmon.sh -log" + echo "rtrmon.sh -config" + echo "rtrmon.sh -update" + echo "rtrmon.sh -setup" + echo "rtrmon.sh -uninstall" + echo "rtrmon.sh -screen" + echo "rtrmon.sh -monitor" + echo "rtrmon.sh -screen/-monitor X" + echo "rtrmon.sh -screen (X) -now" + echo "" + echo " -h | -help (this output)" + echo " -log (display the current log contents)" + echo " -config (configuration utility)" + echo " -update (script update utility)" + echo " -setup (setup/dependencies utility)" + echo " -uninstall (uninstall utility)" + echo " -screen (normal router monitoring using the screen utility)" + echo " -monitor (normal router monitoring operations)" + echo " -screen/-monitor X (X = display screen 1-6 upon execution)" + echo " -screen -now (bypass screen instructions and 5 sec timer)" + echo "" + echo " Examples:" + echo " rtrmon -screen -now (bypass screen timer directly into monitor mode)" + echo " rtrmon -screen 2 (jump to page 2 upon execution using screen)" + echo " rtrmon -screen 3 -now (bypass timer and jump to page 3 using screen)" + echo " rtrmon -monitor 4 (jump to page 4 in monitoring mode)" + echo "" + echo -e "${CClear}" + exit 0 + fi + + # Check to see if the log option is being called, and display through nano + if [ "$1" == "-log" ] + then + vlogs + exit 0 + fi + + # Check to see if the configuration option is being called, and run through setup utility + if [ "$1" == "-config" ] + then + vconfig + echo -e "${CClear}" + exit 0 + fi + + # Check to see if the update option is being called + if [ "$1" == "-update" ] + then + vupdate + echo -e "${CClear}" + exit 0 + fi + + # Check to see if the install option is being called + if [ "$1" = "-setup" ] + then + vsetup + exit 0 + fi + + # Check to see if the uninstall option is being called + if [ "$1" = "-uninstall" ] + then + vuninstall + echo -e "${CClear}" + exit 0 + fi + + # Check to see if the -now parameter is being called to bypass the screen timer + if [ $# -gt 1 ] && [ "$2" = "-now" ] + then + bypassScreenTimer=1 + elif [ $# -gt 2 ] && [ "$3" = "-now" ] + then + bypassScreenTimer2=1 + fi + + # Check to see if the screen option is being called and run operations normally using the screen utility + if [ "$1" = "-screen" ] + then + screen -wipe >/dev/null 2>&1 # Kill any dead screen sessions + sleep 1 + ScreenSess="$(screen -ls | grep "rtrmon" | awk '{print $1}' | cut -d . -f 1)" + if [ -z "$ScreenSess" ] + then + if [ "$bypassScreenTimer" = "1" ] + then + screen -dmS "rtrmon" $APPPATH -monitor + sleep 1 + screen -r rtrmon + elif [ "$bypassScreenTimer2" = "1" ] + then + if [ $# -lt 2 ] || [ -z "$2" ]; then + screen -dmS "rtrmon" $APPPATH -monitor + elif [ "$2" -ge 1 ] && [ "$2" -le 6 ]; then + screen -dmS "rtrmon" $APPPATH -monitor $2 + else + screen -dmS "rtrmon" $APPPATH -monitor + fi + sleep 1 + screen -r rtrmon + else + clear + echo -e "${CClear}Executing ${CGreen}RTRMON v$Version ${CClear}using the SCREEN utility...${CClear}" + echo "" + echo -e "${CClear}IMPORTANT:${CClear}" + echo -e "${CClear}In order to keep RTRMON running in the background,${CClear}" + echo -e "${CClear}properly exit the SCREEN session by using: ${CGreen}CTRL-A + D${CClear}" + echo "" + if [ $# -lt 2 ] || [ -z "$2" ]; then + screen -dmS "rtrmon" $APPPATH -monitor + elif [ "$2" -ge 1 ] && [ "$2" -le 6 ]; then + screen -dmS "rtrmon" $APPPATH -monitor $2 + else + screen -dmS "rtrmon" $APPPATH -monitor + fi + sleep 2 + echo -e "${CClear}Switching to the SCREEN session in T-5 sec...${CClear}" + echo -e "${CClear}" + spinner 5 + screen -r rtrmon + exit 0 + fi + else + if [ "$bypassScreenTimer" = "1" ]; then + sleep 1 + else + clear + echo -e "${CClear}Connecting to existing ${CGreen}RTRMON v$Version ${CClear}SCREEN session...${CClear}" + echo "" + echo -e "${CClear}IMPORTANT:${CClear}" + echo -e "${CClear}In order to keep RTRMON running in the background,${CClear}" + echo -e "${CClear}properly exit the SCREEN session by using: ${CGreen}CTRL-A + D${CClear}" + echo "" + echo -e "${CClear}Switching to the SCREEN session in T-5 sec...${CClear}" + echo -e "${CClear}" + spinner 5 + fi + fi + screen -dr $ScreenSess + exit 0 + fi + + # Check to see if the monitor option is being called and run operations normally + if [ "$1" = "-monitor" ] + then + clear + if [ -f "$CFGPATH" ] && [ -f "/opt/bin/column" ] && [ -f "/opt/bin/timeout" ] && [ -f "/opt/sbin/screen" ] && [ -f "/opt/bin/nmap" ] && [ -f "/opt/bin/jq" ] && [ -f "/opt/bin/iftop" ] + then + printf "\r\033[0K${InvYellow} ${CClear} Please wait..." ; _ConsumeKeypressBuffer_ + source "$CFGPATH" + + if [ -f /root/.config/ookla/speedtest-cli.json ] && \ + [ ! -f /jffs/addons/rtrmon.d/speedtest-cli.json ] + then + cp -fp /root/.config/ookla/speedtest-cli.json /jffs/addons/rtrmon.d/speedtest-cli.json 2>/dev/null + fi + + if [ ! -d "/root/.config/ookla" ] + then + mkdir -p "/root/.config/ookla" + [ -f /jffs/addons/rtrmon.d/speedtest-cli.json ] && \ + cp -fp /jffs/addons/rtrmon.d/speedtest-cli.json /root/.config/ookla/speedtest-cli.json 2>/dev/null + fi + + NextPage="$([ $# -gt 1 ] && echo "$2" | tr -d -c 1-7 || echo)" + if [ -z "$NextPage" ]; then NextPage=1 ; fi + + # Per @Stephen Harrington's suggestion, check NVRAM to see if WiFi is turned on, else mark them as disabled + if [ "$FourBandCustom55624" == "True" ]; then + if [ "$($timeoutcmd$timeoutsec nvram get wl0_radio)" -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + if [ "$($timeoutcmd$timeoutsec nvram get wl1_radio)" -eq 0 ]; then + MaxSpeed52GhzNow=0 + else + MaxSpeed52GhzNow=$MaxSpeed5Ghz + fi + if [ "$($timeoutcmd$timeoutsec nvram get wl2_radio)" -eq 0 ]; then + MaxSpeed6GhzNow=0 + else + MaxSpeed6GhzNow=$MaxSpeed6Ghz + fi + if [ "$($timeoutcmd$timeoutsec nvram get wl3_radio)" -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + elif [ "$FourBandCustom56624" == "True" ]; then + if [ "$($timeoutcmd$timeoutsec nvram get wl0_radio)" -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + if [ "$($timeoutcmd$timeoutsec nvram get wl1_radio)" -eq 0 ]; then + MaxSpeed6GhzNow=0 + else + MaxSpeed6GhzNow=$MaxSpeed6Ghz + fi + if [ "$($timeoutcmd$timeoutsec nvram get wl2_radio)" -eq 0 ]; then + MaxSpeed62GhzNow=0 + else + MaxSpeed62GhzNow=$MaxSpeed6Ghz + fi + if [ "$($timeoutcmd$timeoutsec nvram get wl3_radio)" -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + elif [ "$ThreeBand2456" == "True" ]; then + if [ "$($timeoutcmd$timeoutsec nvram get wl0_radio)" -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + if [ "$($timeoutcmd$timeoutsec nvram get wl1_radio)" -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + if [ "$($timeoutcmd$timeoutsec nvram get wl2_radio)" -eq 0 ]; then + MaxSpeed6GhzNow=0 + else + MaxSpeed6GhzNow=$MaxSpeed6Ghz + fi + elif [ "$ThreeBand2455" == "True" ]; then + if [ "$($timeoutcmd$timeoutsec nvram get wl0_radio)" -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + if [ "$($timeoutcmd$timeoutsec nvram get wl1_radio)" -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + if [ "$($timeoutcmd$timeoutsec nvram get wl2_radio)" -eq 0 ]; then + MaxSpeed52GhzNow=0 + else + MaxSpeed52GhzNow=$MaxSpeed5Ghz + fi + else + if [ "$($timeoutcmd$timeoutsec nvram get wl0_radio)" -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + if [ "$($timeoutcmd$timeoutsec nvram get wl1_radio)" -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + fi + + else + echo -e "${CRed}Error: RTRMON is not configured or does not have all the required dependencies${CClear}" + echo -e "${CRed}installed. Launching 'rtrmon -setup' to install dependencies/complete setup!${CClear}" + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - ERROR: RTRMON is not configured/missing dependencies. Please run the setup tool." >> $LOGFILE + echo "" + echo -e "${CGreen}Launching the Setup Menu in T-5 sec...${CClear}" + spinner 5 + vsetup + echo -e "${CClear}" + exit 0 + fi + fi + +##----------------------------------------## +## Modified by Martinski W. [2024-Nov-03] ## +##----------------------------------------## +# ------------------------------------------------------------------------------------------------------------------------- +# Main RTRMON program initialization +# ------------------------------------------------------------------------------------------------------------------------- + _IgnoreKeypresses_ ON + # Display the logo and indicator that stats are being gathered. + + clear + logoNM + echo -e "\r${CGreen} [Initiating Boot Sequence - Gathering Initial Stats...]" + echo "" + INITIALBOOT=1 + trimlogs + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: RTRMON is initializing for the first time..." >> $LOGFILE + + # Capture initial traffic and store current WAN/WiFi bytes stats + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + if [ $WANOverride == "Auto" ]; then WANIFNAME=$(get_wan_setting ifname); else WANIFNAME=$WANOverride; fi + if [ -z $WANIFNAME ]; then WANIFNAME="eth0"; fi + oldwanrxbytes="$(cat /sys/class/net/$WANIFNAME/statistics/rx_bytes)" + oldwantxbytes="$(cat /sys/class/net/$WANIFNAME/statistics/tx_bytes)" + fi + + if [ "$FourBandCustom55624" == "True" ]; then + ifname5=$($timeoutcmd$timeoutsec nvram get wl0_ifname) + ifname52=$($timeoutcmd$timeoutsec nvram get wl1_ifname) + ifname6=$($timeoutcmd$timeoutsec nvram get wl2_ifname) + ifname24=$($timeoutcmd$timeoutsec nvram get wl3_ifname) + elif [ "$FourBandCustom56624" == "True" ]; then + ifname5=$($timeoutcmd$timeoutsec nvram get wl0_ifname) + ifname6=$($timeoutcmd$timeoutsec nvram get wl1_ifname) + ifname62=$($timeoutcmd$timeoutsec nvram get wl2_ifname) + ifname24=$($timeoutcmd$timeoutsec nvram get wl3_ifname) + elif [ "$ThreeBand2456" == "True" ]; then + ifname24=$($timeoutcmd$timeoutsec nvram get wl0_ifname) + ifname5=$($timeoutcmd$timeoutsec nvram get wl1_ifname) + ifname6=$($timeoutcmd$timeoutsec nvram get wl2_ifname) + elif [ "$ThreeBand2455" == "True" ]; then + ifname24=$($timeoutcmd$timeoutsec nvram get wl0_ifname) + ifname5=$($timeoutcmd$timeoutsec nvram get wl1_ifname) + ifname52=$($timeoutcmd$timeoutsec nvram get wl2_ifname) + else + ifname24=$($timeoutcmd$timeoutsec nvram get wl0_ifname) + ifname5=$($timeoutcmd$timeoutsec nvram get wl1_ifname) + fi + + old24rxbytes="$(cat /sys/class/net/$ifname24/statistics/rx_bytes)" + old24txbytes="$(cat /sys/class/net/$ifname24/statistics/tx_bytes)" + old5rxbytes="$(cat /sys/class/net/$ifname5/statistics/rx_bytes)" + old5txbytes="$(cat /sys/class/net/$ifname5/statistics/tx_bytes)" + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then + old52rxbytes="$(cat /sys/class/net/$ifname52/statistics/rx_bytes)" + old52txbytes="$(cat /sys/class/net/$ifname52/statistics/tx_bytes)" + fi + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then + old6rxbytes="$(cat /sys/class/net/$ifname6/statistics/rx_bytes)" + old6txbytes="$(cat /sys/class/net/$ifname6/statistics/tx_bytes)" + fi + if [ "$FourBandCustom56624" == "True" ]; then + old62rxbytes="$(cat /sys/class/net/$ifname62/statistics/rx_bytes)" + old62txbytes="$(cat /sys/class/net/$ifname62/statistics/tx_bytes)" + fi + oldlanrxbytes="$(cat /sys/class/net/br0/statistics/rx_bytes)" + oldlantxbytes="$(cat /sys/class/net/br0/statistics/tx_bytes)" + + #Get the Initial VPN stats + GetVPNWGIPCITY + GetVPNWGStats + + # Get initial TOP stats to average across the interval period + RM_ELAPSED_TIME=0 + RM_START_TIME="$(date +%s)" + + ##----------------------------------------## + ## Modified by Martinski W. [2024-Nov-04] ## + ##----------------------------------------## + timer=0 + lastTimerSec=0 + updateTimer=true + savedInterval="$Interval" + Interval="$bootInterval" + + # Initial Boot Sequence Loop # + while [ "$timer" -lt "$Interval" ] + do + if "$updateTimer" + then + updateTimer=false + timer="$((timer+1))" + lastTimerSec="$(date +%s)" + gettopstats "$timer" + fi + preparebar 53 "|" + progressbaroverride "$timer" "$Interval" "" "s" "Standard" + + ## Prevent repeatedly fast key presses from updating the timer ## + [ "$(date +%s)" -gt "$lastTimerSec" ] && updateTimer=true + done + + calculatestats + oldstats + + clear + INITIALBOOT=0 + Interval="$savedInterval" + +# ------------------------------------------------------------------------------------------------------------------------- +# Main loop that calls functions to perform all necessary calculations across the interval period +# ------------------------------------------------------------------------------------------------------------------------- +##----------------------------------------## +## Modified by Martinski W. [2024-Nov-03] ## +##----------------------------------------## +while true +do + + _SetUpTimeoutCmdVars_ + _SetLAN_HostName_ + _IgnoreKeypresses_ ON + + if [ "$NextPage" = "1" ]; then + DisplayPage1 + echo "" + elif [ "$NextPage" = "2" ]; then + DisplayPage2 + echo "" + elif [ "$NextPage" = "3" ]; then + DisplayPage3 + echo "" + elif [ "$NextPage" = "4" ]; then + DisplayPage4 + echo "" + elif [ "$NextPage" = "5" ]; then + DisplayPage5 + #echo "" + elif [ "$NextPage" = "6" ]; then + DisplayPage6 + #echo "" + elif [ "$NextPage" = "7" ]; then + DisplayPage7 + fi + + # Reset stats after the UI has finished drawing + memused1=0 + memfree1=0 + memshrd1=0 + membuff1=0 + memcach1=0 + memused2=0 + memfree2=0 + memshrd2=0 + membuff2=0 + memcach2=0 + cpuusr1=0 + cpusys1=0 + cpunice1=0 + cpuidle1=0 + displaycpuusr1=0 + displaycpusys1=0 + displaycpunice1=0 + displaycpuidle1=0 + displaycpuirq1=0 + + # Get fresh WAN stats + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + oldwanrxbytes="$(cat /sys/class/net/$WANIFNAME/statistics/rx_bytes)" + oldwantxbytes="$(cat /sys/class/net/$WANIFNAME/statistics/tx_bytes)" + fi + old24rxbytes="$(cat /sys/class/net/$ifname24/statistics/rx_bytes)" + old24txbytes="$(cat /sys/class/net/$ifname24/statistics/tx_bytes)" + old5rxbytes="$(cat /sys/class/net/$ifname5/statistics/rx_bytes)" + old5txbytes="$(cat /sys/class/net/$ifname5/statistics/tx_bytes)" + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then + old52rxbytes="$(cat /sys/class/net/$ifname52/statistics/rx_bytes)" + old52txbytes="$(cat /sys/class/net/$ifname52/statistics/tx_bytes)" + fi + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then + old6rxbytes="$(cat /sys/class/net/$ifname6/statistics/rx_bytes)" + old6txbytes="$(cat /sys/class/net/$ifname6/statistics/tx_bytes)" + fi + if [ "$FourBandCustom56624" == "True" ]; then + old62rxbytes="$(cat /sys/class/net/$ifname62/statistics/rx_bytes)" + old62txbytes="$(cat /sys/class/net/$ifname62/statistics/tx_bytes)" + fi + oldlanrxbytes="$(cat /sys/class/net/br0/statistics/rx_bytes)" + oldlantxbytes="$(cat /sys/class/net/br0/statistics/tx_bytes)" + + # Get fresh VPN stats + echo "" + GetVPNWGIPCITY loop + GetVPNWGStats + + printf "${CGreen}\r " + printf "${CGreen}\r" + + + # Run through the stats gathering loop based on the current interval + RM_ELAPSED_TIME=0 + RM_START_TIME="$(date +%s)" + + ##----------------------------------------## + ## Modified by Martinski W. [2024-Nov-05] ## + ##----------------------------------------## + timer=0 + lastTimerSec=0 + updateTimer=true + pausedTimerEnabled=false + pausedTimerDispStr="" + + # Main Loop # + while [ "$timer" -lt "$Interval" ] + do + if "$updateTimer" + then + updateTimer=false + timer="$((timer+1))" + lastTimerSec="$(date +%s)" + gettopstats "$timer" + fi + preparebar 46 "|" + progressbaroverride "$timer" "$Interval" "" "s" "Standard" + if [ "$timerReset" = "1" ] ; then timer="$Interval" ; fi + + ## Prevent repeatedly fast key presses from updating the timer ## + [ "$(date +%s)" -gt "$lastTimerSec" ] && updateTimer=true + done + + # Do a fresh round of stats and save them to the old stats for display purposes + calculatestats + oldstats + clear + + if [ "$autorotate" = "1" ] && [ "$timer" -ge "$Interval" ] + then + if [ "$NextPage" = "1" ]; then NextPage=2 #DisplayPage2# + elif [ "$NextPage" = "2" ]; then NextPage=3 #DisplayPage3# + elif [ "$NextPage" = "3" ]; then NextPage=4 #DisplayPage4# + elif [ "$NextPage" = "4" ]; then NextPage=5 #DisplayPage5# + elif [ "$NextPage" = "5" ]; then NextPage=6 #DisplayPage6# + elif [ "$NextPage" = "6" ]; then NextPage=7 #DisplayPage7# + elif [ "$NextPage" = "7" ]; then NextPage=1 #DisplayPage1# + fi + fi + + prevHideOpts=X + prevSortByOpt=X +done + +_IgnoreKeypresses_ OFF + +exit 0 + +} #2>&1 | tee $LOG | logger -t $(basename $0)[$$] # uncomment/comment to enable/disable debug mode From 699da5c1c439f0e6e5614ccf85bf57c336ee2e58 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Thu, 4 Dec 2025 19:22:37 -0500 Subject: [PATCH 02/62] Update rtrmon.sh --- rtrmon.sh | 595 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 375 insertions(+), 220 deletions(-) diff --git a/rtrmon.sh b/rtrmon.sh index a3c1546..fdb7cae 100644 --- a/rtrmon.sh +++ b/rtrmon.sh @@ -15,7 +15,7 @@ # # Please use the 'sh rtrmon.sh -setup' command to configure the necessary parameters that match your environment the best! # -# Last Modified: 2025-Nov-16 +# Last Modified: 2025-Dec-4 ########################################################################################################################### #Preferred standard router binaries path @@ -24,7 +24,7 @@ export PATH="/sbin:/bin:/usr/sbin:/usr/bin:$PATH" # ------------------------------------------------------------------------------------------------------------------------- # System Variables (Do not change beyond this point or this may change the programs ability to function correctly) # ------------------------------------------------------------------------------------------------------------------------- -Version="2.2.3" +Version="2.2.4" Beta=0 ScreenshotMode=0 LOGFILE="/jffs/addons/rtrmon.d/rtrmon.log" # Logfile path/name that captures important date/time events - change @@ -4660,7 +4660,7 @@ if [ "$NCView" = "WG" ] # ------------------------------------------------------------------------------------------------------------------------- ##------------------------------------------## -## Modified by ExtremeFiretop [2024-Aug-06] ## +## Modified by ExtremeFiretop [2025-Dec-03] ## ##------------------------------------------## # This function displays the stats UI for page 3 DisplayPage7() @@ -4795,85 +4795,93 @@ DisplayPage7() echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" echo "" + # --- Local 2.4 GHz: only show heading if clients exist on the base iface --- if [ "$MaxSpeed24GhzNow" != "0" ]; then - if [ "$w24updown" == "UP" ]; then - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 2.4GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname24 ${CClear}" - else + section_output="$(attachedwificlients "$ifname24")" + if [ -n "$section_output" ] && \ + ! echo "$section_output" | grep -q "No Devices Connected"; then echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 2.4GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname24 ${CClear}" + printf '%s\n' "$section_output" + echo "" fi - attachedwificlients "$ifname24" - echo "" else echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 2.4GHz ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" echo "" fi + + # --- Local 5.0 GHz: only show if clients on base iface --- #Testing #MaxSpeed5GhzNow=0 #testing #w5updown="UP" #testing if [ "$MaxSpeed5GhzNow" != "0" ]; then - if [ "$w5updown" == "UP" ]; then - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname5 ${CClear}" - else + section_output="$(attachedwificlients "$ifname5")" + if [ -n "$section_output" ] && \ + ! echo "$section_output" | grep -q "No Devices Connected"; then echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname5 ${CClear}" + printf '%s\n' "$section_output" + echo "" fi - attachedwificlients "$ifname5" - echo "" else echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" echo "" fi + + # --- Local 5.0 GHz (2): only show if clients on base iface --- #Testing #FourBandCustom55624="True" #testing #MaxSpeed52GhzNow=0 #testing #w52updown="UP" #testing if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then if [ "$MaxSpeed52GhzNow" != "0" ]; then - if [ "$w52updown" == "UP" ]; then - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz (2) ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname52 ${CClear}" - else + section_output="$(attachedwificlients "$ifname52")" + if [ -n "$section_output" ] && \ + ! echo "$section_output" | grep -q "No Devices Connected"; then echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz (2) ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname52 ${CClear}" + printf '%s\n' "$section_output" + echo "" fi - attachedwificlients "$ifname52" - #attachedwificlients "$ifname5" #testing - echo "" else echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz (2) ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" echo "" fi fi + + # --- Local 6.0 GHz: only show if clients on base iface --- #Testing #ThreeBand2456="True" #testing #MaxSpeed6GhzNow=1 #testing #w6updown="UP" #testing - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then + if [ "$FourBandCustom55624" == "True" ] || \ + [ "$ThreeBand2456" == "True" ] || \ + [ "$FourBandCustom56624" == "True" ]; then if [ "$MaxSpeed6GhzNow" != "0" ]; then - if [ "$w6updown" == "UP" ]; then - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname6 ${CClear}" - else + section_output="$(attachedwificlients "$ifname6")" + if [ -n "$section_output" ] && \ + ! echo "$section_output" | grep -q "No Devices Connected"; then echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname6 ${CClear}" + printf '%s\n' "$section_output" + echo "" fi - attachedwificlients "$ifname6" - #attachedwificlients "$ifname5" #testing - echo "" else echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" echo "" fi fi + + # --- Local 6.0 GHz (2): only show if clients on base iface --- #Testing #FourBandCustom56624="True" #testing #MaxSpeed62GhzNow=0 #testing #w62updown="UP" #testing if [ "$FourBandCustom56624" == "True" ]; then if [ "$MaxSpeed62GhzNow" != "0" ]; then - if [ "$w62updown" == "UP" ]; then - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz (2) ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname62 ${CClear}" - else + section_output="$(attachedwificlients "$ifname62")" + if [ -n "$section_output" ] && \ + ! echo "$section_output" | grep -q "No Devices Connected"; then echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz (2) ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname62 ${CClear}" + printf '%s\n' "$section_output" + echo "" fi - attachedwificlients "$ifname62" - #attachedwificlients "$ifname5" #testing - echo "" else echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz (2) ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" echo "" @@ -4882,19 +4890,41 @@ DisplayPage7() # Guest Network Clients - Thanks to @ColinTaylor for this methodology of stepping through legit guest network interfaces cp -f /jffs/addons/rtrmon.d/temparp.txt /jffs/addons/rtrmon.d/temparpvlan.txt - for guestiface in $(nvram get wl0_vifs) $(nvram get wl1_vifs) $(nvram get wl2_vifs) $(nvram get wl3_vifs) - do - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local Guest Wi-Fi ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $guestiface ${CClear}" + + for guestiface in $(nvram get wl0_vifs) $(nvram get wl1_vifs) \ + $(nvram get wl2_vifs) $(nvram get wl3_vifs) + do + guestssid=$(nvram get ${guestiface}_ssid 2>/dev/null) + # Skip VIFs with no SSID at all + [ -z "$guestssid" ] && continue + + bridge_name="" + # Find which bridge this VIF is enslaved to by checking /sys/class/net/br*/brif + for br in $(ls /sys/class/net 2>/dev/null | grep '^br'); do + if [ -d "/sys/class/net/$br/brif/$guestiface" ]; then + bridge_name="$br" + break + fi + done + + if [ -n "$bridge_name" ] && [ "$bridge_name" != "br0" ]; then + guestlabel="Guest Wi-Fi" + else + guestlabel="Local Wi-Fi" + fi + + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}${guestlabel}: ${CGreen}${guestssid}${CWhite} ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $guestiface ${CClear}" + attachedguestclients "$guestiface" echo "" - done + done for vlanlabels in $(nvram get apg_ifnames) - do + do echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local VLAN/AiMesh VLAN ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $vlanlabels ${CClear}" attachedvlanclients "$vlanlabels" echo "" - done + done echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local LAN/Non-VLAN AiMesh ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: br0 ${CClear}" #Remove non-LAN records @@ -4962,8 +4992,11 @@ attachedwificlients () maxclientcount=$(cat /jffs/addons/rtrmon.d/wificlients$iface.txt | wc -l) rm -f /jffs/addons/rtrmon.d/clientlist$iface.txt dhcpleases="$(read_all_dhcp_leases)" - local clients=$(nvram get custom_clientlist) - local maxextractcount=$(echo "$clients" | awk -F'>>' '{count=0; for (i=1; i<=NF; i++) if ($i != "") count++; print count}') + local clients + clients="$(nvram get custom_clientlist)" + # Number of '<...>' entries = NF - 1 (first field is empty before first '<') + local maxextractcount + maxextractcount=$(echo "$clients" | awk -F'<' '{print NF}') local clientcount=0 while [ $clientcount -le $maxclientcount ] @@ -4972,12 +5005,11 @@ attachedwificlients () conntime="" clientip="" paddedclientip="" + clientcount=$((clientcount+1)) local clientmac=$(awk 'NR=='$clientcount' {print $2}' /jffs/addons/rtrmon.d/wificlients$iface.txt) - if [ -z "$clientmac" ]; then - continue - fi + [ -z "$clientmac" ] && continue networktime=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/in network/ {print $3}') 2>/dev/null conntime=$(date -d@$networktime -u +%Hh:%Mm) 2>/dev/null @@ -4988,81 +5020,116 @@ attachedwificlients () sigstrength=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/smoothed rssi:/ {print $3}') 2>/dev/null maclower=$(echo "$clientmac" | awk '{print tolower($0)}') 2>/dev/null - # --- Unified MLD MAC retrieval logic --- - lookup_mac=$(get_lookup_mac "$maclower" "$dhcpleases") - - # Find IPs for the given MAC address in the ARP table - ips=$(grep "$maclower" "/jffs/addons/rtrmon.d/temparp.txt" | awk '{print $1}') 2>/dev/null + # For WiFi 7 / MLO clients the MAC used by wl (assoclist) may NOT be + # the same MAC that appears in ARP/DHCP. Start with the assoc MAC + # as canonical, then override if we find a better ARP match. + canonical_mac="$clientmac" + canonlower="$maclower" - # Iterate over the IPs to find the reachable one - for ip in $ips; do - # Check the status of the IP in the neighbor table - arp_status=$(ip neigh show | grep -w "$ip" | awk '{print $NF}') 2>/dev/null + # --- MLD / dnsmasq lookup helper --- + lookup_mac=$(get_lookup_mac "$maclower" "$dhcpleases") - # Check if the current IP is reachable - if [ -z "$arp_status" ] || { [ "$arp_status" != "REACHABLE" ] && [ "$arp_status" != "DELAY" ]; }; then - if [ -z "$sigstrength" ]; then - conntime="STALE" + # 1) Try to find IPs for this MAC directly in the temp ARP table + ips=$(awk -v mac="$maclower" ' + BEGIN{IGNORECASE=1} + tolower($4)==mac {print $1} + ' /jffs/addons/rtrmon.d/temparp.txt 2>/dev/null) + + # 2) If that fails, try a fuzzy match using the middle 4 bytes of the MAC + if [ -z "$ips" ]; then + mac_mid4=$(echo "$maclower" | awk -F: '{print $2":"$3":"$4":"$5}') + if [ -n "$mac_mid4" ]; then + arp_line=$(awk -v mid="$mac_mid4" ' + BEGIN{IGNORECASE=1} + index(tolower($4), mid) > 0 {print; exit} + ' /jffs/addons/rtrmon.d/temparp.txt 2>/dev/null) + if [ -n "$arp_line" ]; then + clientip=$(echo "$arp_line" | awk '{print $1}') + canonical_mac=$(echo "$arp_line" | awk '{print $4}') + canonlower=$(echo "$canonical_mac" | awk '{print tolower($0)}') fi - continue - else - # Set the clientip to the current IP if it is reachable or delay - clientip="$ip" - break fi - done + fi - # Fallback to using the ARP table if no reachable IP was found + # 3) If we had multiple IPs from a direct match, prefer one that is REACHABLE/DELAY + if [ -z "$clientip" ] && [ -n "$ips" ]; then + for ip in $ips; do + arp_status=$(ip neigh show | grep -w "$ip" | awk '{print $NF}') 2>/dev/null + if [ -z "$arp_status" ] || { [ "$arp_status" != "REACHABLE" ] && [ "$arp_status" != "DELAY" ]; }; then + [ -z "$sigstrength" ] && conntime="STALE" + continue + else + clientip="$ip" + break + fi + done + [ -z "$clientip" ] && clientip=$(echo "$ips" | tail -n 1) + fi + + # 4) Final fallback: /proc/net/arp using the canonical MAC if [ -z "$clientip" ]; then - clientip=$(cat /proc/net/arp | grep "$maclower" | awk '{print $1}' | sort | uniq | tail -n 1) 2>/dev/null + clientip=$(awk -v mac="$canonlower" ' + BEGIN{IGNORECASE=1} + tolower($4)==mac {print $1} + ' /proc/net/arp 2>/dev/null | sort | uniq | tail -n 1) fi - paddedclientip=$(echo "${clientip}" | grep -o -E '([0-9]*\.|[0-9]*)' | awk '{printf( "%03d\n", $1)}' | tr '\n' '.' | sed 's/.$//') 2>/dev/null + paddedclientip=$(echo "${clientip}" | \ + grep -o -E '([0-9]*\.|[0-9]*)' | \ + awk '{printf( "%03d\n", $1)}' | tr '\n' '.' | sed 's/.$//') 2>/dev/null - #calcs + # Traffic/rate conversions txtotalgb=$(echo $txtotalbytes | awk -v txb=$txtotalbytes 'BEGIN{printf "%0.2f\n", txb/1024/1024/1024}') 2>/dev/null rxtotalgb=$(echo $rxtotalbytes | awk -v rxb=$rxtotalbytes 'BEGIN{printf "%0.2f\n", rxb/1024/1024/1024}') 2>/dev/null txratembps=$(echo $txratekbps | awk -v txm=$txratekbps 'BEGIN{printf "%0.1f\n", txm/1000}') 2>/dev/null rxratembps=$(echo $rxratekbps | awk -v rxm=$rxratekbps 'BEGIN{printf "%0.1f\n", rxm/1000}') 2>/dev/null + # Try custom_clientlist first (match either assoc MAC or canonical ARP MAC) local found=0 - local counter=0 + local counter=2 + canonupper=$(echo "$canonical_mac" | tr 'a-f' 'A-F') while [ $counter -le $maxextractcount ] do - counter=$((counter+1)) - local clientextract="$(echo $clients | cut -d "<" -f$counter | cut -d ">" -f1,2)" + local clientextract + clientextract="$(echo "$clients" | cut -d "<" -f"$counter" | cut -d ">" -f1,2)" - if [ -z "$clientextract" ]; then - break - fi + [ -z "$clientextract" ] && { counter=$((counter+1)); continue; } - local client="$(echo $clientextract | awk -F ">" '{print $1}')" - local mac="$(echo $clientextract | awk -F ">" '{print $2}')" + local client + local mac + client="$(echo "$clientextract" | awk -F ">" '{print $1}')" + mac="$(echo "$clientextract" | awk -F ">" '{print $2}')" - if [ "$mac" == "$clientmac" ]; then - clientname=$client + if [ "$mac" = "$clientmac" ] || [ "$mac" = "$canonupper" ]; then + clientname="$client" found=1 break fi + + counter=$((counter+1)) done - # Fallback to using dnsmasq.leases if no match found + + # Fallback: name from dnsmasq leases using lookup_mac if [ $found -ne 1 ]; then clientname=$(echo "$dhcpleases" | grep -i "$lookup_mac" | awk '{print $4}') 2>/dev/null - if [ -z "$clientname" ] || [ "$clientname" == "*" ]; then + if [ -z "$clientname" ] || [ "$clientname" = "*" ]; then clientname="UNKNOWN" fi fi + if [ -n "$paddedclientip" ] && [ "$paddedclientip" != "000.000.000.000" ]; then - # Add the check for already processed clients - if grep -qi "$clientmac" /jffs/addons/rtrmon.d/processed_clients.txt; then - # Skip processing if the device was already handled + # Track by canonical MAC so the same device won't show again under LAN + if grep -qi "$canonupper" /jffs/addons/rtrmon.d/processed_clients.txt 2>/dev/null; then continue else - echo "$clientmac" >> /jffs/addons/rtrmon.d/processed_clients.txt + echo "$canonupper" >> /jffs/addons/rtrmon.d/processed_clients.txt fi - #delete entry from temparp table - sed -i -e '/'$maclower'/d' /jffs/addons/rtrmon.d/temparp.txt - echo "$clientname,$paddedclientip,$clientmac,$conntime,$txtotalgb,$rxtotalgb,$txratembps,$rxratembps,$sigstrength" >> /jffs/addons/rtrmon.d/clientlist$iface.txt + + # Remove this canonical MAC from the temp ARP table + sed -i -e '/'$canonlower'/d' /jffs/addons/rtrmon.d/temparp.txt + + echo "$clientname,$paddedclientip,$canonupper,$conntime,$txtotalgb,$rxtotalgb,$txratembps,$rxratembps,$sigstrength" \ + >> /jffs/addons/rtrmon.d/clientlist$iface.txt fi done @@ -5078,20 +5145,27 @@ attachedwificlients () fi } + # ------------------------------------------------------------------------------------------------------------------------- # attachedguestclients pulls connected client info from wl, arp and nvram ##------------------------------------------## -## Modified by ExtremeFiretop [2024-Aug-06] ## +## Modified by ExtremeFiretop [2025-Dec-03] ## +##------------------------------------------## +# attachedguestclients pulls connected client info from wl, arp and nvram +##------------------------------------------## +## Modified by ExtremeFiretop [2025-Dec-04] ## ##------------------------------------------## attachedguestclients() { iface="$1" rm -f /jffs/addons/rtrmon.d/wificlients$iface.txt - wl -i $iface assoclist > /jffs/addons/rtrmon.d/wificlients$iface.txt + wl -i "$iface" assoclist > /jffs/addons/rtrmon.d/wificlients$iface.txt maxclientcount=$(cat /jffs/addons/rtrmon.d/wificlients$iface.txt | wc -l) rm -f /jffs/addons/rtrmon.d/clientlist$iface.txt dhcpleases="$(read_all_dhcp_leases)" - local clients=$(nvram get custom_clientlist) - local maxextractcount=$(echo "$clients" | awk -F'>>' '{count=0; for (i=1; i<=NF; i++) if ($i != "") count++; print count}') + local clients + clients="$(nvram get custom_clientlist)" + local maxextractcount + maxextractcount=$(echo "$clients" | awk -F'<' '{print NF}') local clientcount=0 while [ $clientcount -le $maxclientcount ] @@ -5115,82 +5189,132 @@ attachedguestclients() { rxratekbps=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rate of last rx pkt:/ {print $6}') 2>/dev/null sigstrength=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/smoothed rssi:/ {print $3}') 2>/dev/null maclower=$(echo "$clientmac" | awk '{print tolower($0)}') 2>/dev/null - # --- Unified MLD MAC retrieval logic --- - lookup_mac=$(get_lookup_mac "$maclower" "$dhcpleases") - # Find IPs for the given MAC address in the ARP table - ips=$(grep "$maclower" "/jffs/addons/rtrmon.d/temparp.txt" | awk '{print $1}') 2>/dev/null + # Start with assoc MAC as canonical, may override with ARP MAC (WiFi7 / MLO case). + canonical_mac="$clientmac" + canonlower="$maclower" + + # 1) Try ARP in temparp.txt for canonical MAC. + ips=$(awk -v mac="$canonlower" ' + BEGIN{IGNORECASE=1} + tolower($4)==mac {print $1} + ' /jffs/addons/rtrmon.d/temparp.txt 2>/dev/null) + + # 2) If no direct ARP match, try fuzzy match on middle 4 bytes. + if [ -z "$ips" ]; then + mac_mid4=$(echo "$maclower" | awk -F: '{print $2":"$3":"$4":"$5}') + if [ -n "$mac_mid4" ]; then + arp_line=$(awk -v mid="$mac_mid4" ' + BEGIN{IGNORECASE=1} + index(tolower($4), mid) > 0 {print; exit} + ' /jffs/addons/rtrmon.d/temparp.txt 2>/dev/null) + if [ -n "$arp_line" ]; then + clientip=$(echo "$arp_line" | awk '{print $1}') + canonical_mac=$(echo "$arp_line" | awk '{print $4}') + canonlower=$(echo "$canonical_mac" | awk '{print tolower($0)}') + fi + fi + fi - # Iterate over the IPs to find the reachable one - for ip in $ips; do - # Check the status of the IP in the neighbor table + # 3) If we had a set of ARP IPs from direct match, choose REACHABLE/DELAY if possible. + if [ -z "$clientip" ] && [ -n "$ips" ]; then + for ip in $ips; do arp_status=$(ip neigh show | grep -w "$ip" | awk '{print $NF}') 2>/dev/null - - # Check if the current IP is reachable if [ -z "$arp_status" ] || { [ "$arp_status" != "REACHABLE" ] && [ "$arp_status" != "DELAY" ]; }; then - if [ -z "$sigstrength" ]; then - conntime="STALE" - fi - continue + [ -z "$sigstrength" ] && conntime="STALE" + continue else - # Set the clientip to the current IP if it is reachable or delay - clientip="$ip" - break + clientip="$ip" + break fi - done + done + [ -z "$clientip" ] && clientip=$(echo "$ips" | tail -n 1) + fi + + # 4) Final ARP fallback: /proc/net/arp with canonical MAC. + if [ -z "$clientip" ]; then + clientip=$(awk -v mac="$canonlower" ' + BEGIN{IGNORECASE=1} + tolower($4)==mac {print $1} + ' /proc/net/arp 2>/dev/null | sort | uniq | tail -n 1) + fi - # Fallback to using the ARP table or DHCP leases if no reachable IP was found + # 5) NEW: If ARP could not give us an IP (guest VLAN case), + # fall back to dnsmasq leases for this canonical MAC. if [ -z "$clientip" ]; then - # Try to get the last IP from the ARP table - clientip=$(cat /proc/net/arp | grep "$maclower" | awk '{print $1}' | sort | uniq | tail -n 1) 2>/dev/null + lease_line=$(echo "$dhcpleases" | awk -v mac="$canonlower" ' + BEGIN{IGNORECASE=1} + tolower($2)==mac {print; exit} + ') + if [ -n "$lease_line" ]; then + clientip=$(echo "$lease_line" | awk '{print $3}') + fi fi - paddedclientip=$(echo "${clientip}" | grep -o -E '([0-9]*\.|[0-9]*)' | awk '{printf( "%03d\n", $1)}' | tr '\n' '.' | sed 's/.$//') 2>/dev/null + paddedclientip=$(echo "${clientip}" | \ + grep -o -E '([0-9]*\.|[0-9]*)' | \ + awk '{printf( "%03d\n", $1)}' | tr '\n' '.' | sed 's/.$//') 2>/dev/null - #calcs + # Conversions txtotalgb=$(echo $txtotalbytes | awk '{printf "%0.2f", $1/1024/1024/1024}') 2>/dev/null rxtotalgb=$(echo $rxtotalbytes | awk '{printf "%0.2f", $1/1024/1024/1024}') 2>/dev/null txratembps=$(echo $txratekbps | awk '{printf "%0.1f", $1/1000}') 2>/dev/null rxratembps=$(echo $rxratekbps | awk '{printf "%0.1f", $1/1000}') 2>/dev/null + # Resolve client name from custom_clientlist (assoc MAC OR canonical ARP MAC). local found=0 - local counter=0 + local counter=2 + canonupper=$(echo "$canonical_mac" | tr 'a-f' 'A-F') while [ $counter -le $maxextractcount ] do - counter=$((counter+1)) - local clientextract="$(echo $clients | cut -d "<" -f$counter | cut -d ">" -f1,2)" + local clientextract + clientextract="$(echo "$clients" | cut -d "<" -f"$counter" | cut -d ">" -f1,2)" - if [ -z "$clientextract" ]; then - break - fi + [ -z "$clientextract" ] && { counter=$((counter+1)); continue; } - local client=$(echo $clientextract | awk -F ">" '{print $1}') - local mac=$(echo $clientextract | awk -F ">" '{print $2}') + local client + local mac + client="$(echo "$clientextract" | awk -F ">" '{print $1}')" + mac="$(echo "$clientextract" | awk -F ">" '{print $2}')" - if [ "$mac" == "$clientmac" ]; then - clientname=$client - found=1 - break - fi + if [ "$mac" = "$clientmac" ] || [ "$mac" = "$canonupper" ]; then + clientname="$client" + found=1 + break + fi + + counter=$((counter+1)) done - # Fallback to using dnsmasq.leases if no match found + + # Fallback: name from dnsmasq leases for canonical MAC. if [ $found -ne 1 ]; then - clientname=$(echo "$dhcpleases" | grep -i "$lookup_mac" | awk '{print $4}') 2>/dev/null - if [ -z "$clientname" ] || [ "$clientname" == "*" ]; then - clientname="UNKNOWN" - fi + lookup_mac="$canonlower" + clientname=$(echo "$dhcpleases" | awk -v mac="$lookup_mac" ' + BEGIN{IGNORECASE=1} + tolower($2)==mac {print $4; exit} + ') 2>/dev/null + if [ -z "$clientname" ] || [ "$clientname" = "*" ]; then + clientname="UNKNOWN" + fi fi + if [ -n "$paddedclientip" ] && [ "$paddedclientip" != "000.000.000.000" ]; then - # Add the check for already processed clients - if grep -qi "$clientmac" /jffs/addons/rtrmon.d/processed_clients.txt; then - # Skip processing if the device was already handled - continue - else - echo "$clientmac" >> /jffs/addons/rtrmon.d/processed_clients.txt - fi - #delete entry from temparp table - sed -i -e '/'$maclower'/d' /jffs/addons/rtrmon.d/temparp.txt - echo "$clientname,$paddedclientip,$clientmac,$conntime,$txtotalgb,$rxtotalgb,$txratembps,$rxratembps,$sigstrength" >> /jffs/addons/rtrmon.d/clientlist$iface.txt + # Mark canonical MAC as processed so it won't also show under LAN. + if grep -qi "$canonupper" /jffs/addons/rtrmon.d/processed_clients.txt 2>/dev/null; then + continue + else + echo "$canonupper" >> /jffs/addons/rtrmon.d/processed_clients.txt + fi + + # Prefer to remove from temparp.txt by IP (handles cases where ARP MAC != client MAC). + if [ -n "$clientip" ]; then + sed -i -e "/^$clientip[[:space:]]/d" /jffs/addons/rtrmon.d/temparp.txt + else + sed -i -e '/'$canonlower'/d' /jffs/addons/rtrmon.d/temparp.txt + fi + + echo "$clientname,$paddedclientip,$canonupper,$conntime,$txtotalgb,$rxtotalgb,$txratembps,$rxratembps,$sigstrength" \ + >> /jffs/addons/rtrmon.d/clientlist$iface.txt fi done @@ -5206,17 +5330,21 @@ attachedguestclients() { fi } + # ------------------------------------------------------------------------------------------------------------------------- # attachedvlanclients pulls connected client info from wl, arp and nvram +# attachedvlanclients pulls connected client info from wl, arp and nvram attachedvlanclients() { iface="$1" vlansfound=1 maxclientcount=$(cat /jffs/addons/rtrmon.d/temparpvlan.txt | wc -l) rm -f /jffs/addons/rtrmon.d/vlanclients$iface.txt dhcpleases="$(read_all_dhcp_leases)" - local clients=$(nvram get custom_clientlist) - local maxextractcount=$(echo "$clients" | awk -F'>>' '{count=0; for (i=1; i<=NF; i++) if ($i != "") count++; print count}') + local clients + clients="$(nvram get custom_clientlist)" + local maxextractcount + maxextractcount=$(echo "$clients" | awk -F'<' '{print NF}') local clientcount=0 while [ $clientcount -le $maxclientcount ] @@ -5233,7 +5361,6 @@ attachedvlanclients() { continue fi - # Convert the MAC address to uppercase and store it in a new variable macupper=$(echo "$clientmac" | tr 'a-f' 'A-F') macprefix=$(echo "$macupper" | awk -F ':' '{print $1":"$2":"$3":"$4":"$5}') 2>/dev/null clientbridgeid=$(awk 'NR=='$clientcount' {print $6}' /jffs/addons/rtrmon.d/temparpvlan.txt | xargs) @@ -5245,16 +5372,13 @@ attachedvlanclients() { interfaces=$(ip link show | grep -E 'wl|wlan' | awk -F: '{print $2}' | tr -d ' ') for wirelessface in $interfaces; do - # Suppress both standard output and error from the wl command and check for the MAC if wl -i "$wirelessface" assoclist 2>/dev/null | grep -iq "$macprefix"; then - # Save the interface name into the variable interface_name="$wirelessface" continue fi done networktime=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/in network/ {print $3}') 2>/dev/null - # Set conntime to "OFFLINE" if networktime is empty if [ -z "$networktime" ]; then conntime="AiMesh" else @@ -5266,81 +5390,71 @@ attachedvlanclients() { rxratekbps=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/rate of last rx pkt:/ {print $6}') 2>/dev/null sigstrength=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/smoothed rssi:/ {print $3}') 2>/dev/null - # --- Unified MLD MAC lookup for VLAN clients --- maclower=$(echo "$clientmac" | awk '{print tolower($0)}') 2>/dev/null lookup_mac=$(get_lookup_mac "$maclower" "$dhcpleases") - # Find IPs for the given MAC address in the ARP table ips=$(grep "$clientmac" "/jffs/addons/rtrmon.d/temparp.txt" | awk '{print $1}') 2>/dev/null - # Iterate over the IPs to find the reachable one for ip in $ips; do - # Check the status of the IP in the neighbor table arp_status=$(ip neigh show | grep -w "$ip" | awk '{print $NF}') 2>/dev/null - - # Check if the current IP is reachable if [ -z "$arp_status" ] || { [ "$arp_status" != "REACHABLE" ] && [ "$arp_status" != "DELAY" ]; }; then if [ -z "$sigstrength" ]; then conntime="STALE" fi continue else - # Set the clientip to the current IP if it is reachable or delay clientip="$ip" break fi done - # Fallback to using the ARP table if no reachable IP was found if [ -z "$clientip" ]; then clientip=$(cat /proc/net/arp | grep "$clientmac" | awk '{print $1}' | sort | uniq | tail -n 1) 2>/dev/null fi paddedclientip=$(echo "$clientip" | awk -F '.' '{printf "%03d.%03d.%03d.%03d\n", $1, $2, $3, $4}') 2>/dev/null - #calcs txtotalgb=$(echo $txtotalbytes | awk '{printf "%0.2f", $1/1024/1024/1024}') 2>/dev/null rxtotalgb=$(echo $rxtotalbytes | awk '{printf "%0.2f", $1/1024/1024/1024}') 2>/dev/null txratembps=$(echo $txratekbps | awk '{printf "%0.1f", $1/1000}') 2>/dev/null rxratembps=$(echo $rxratekbps | awk '{printf "%0.1f", $1/1000}') 2>/dev/null local found=0 - local counter=0 + local counter=2 while [ $counter -le $maxextractcount ] do - counter=$((counter+1)) - local clientextract="$(echo $clients | cut -d "<" -f$counter | cut -d ">" -f1,2)" + local clientextract + clientextract="$(echo "$clients" | cut -d "<" -f"$counter" | cut -d ">" -f1,2)" - if [ -z "$clientextract" ]; then - break - fi + [ -z "$clientextract" ] && { counter=$((counter+1)); continue; } - local client="$(echo $clientextract | awk -F ">" '{print $1}')" - local mac="$(echo $clientextract | awk -F ">" '{print $2}')" + local client + local mac + client="$(echo "$clientextract" | awk -F ">" '{print $1}')" + mac="$(echo "$clientextract" | awk -F ">" '{print $2}')" - if [ "$mac" == "$macupper" ]; then - clientname=$client + if [ "$mac" = "$macupper" ]; then + clientname="$client" found=1 break fi + counter=$((counter+1)) done - # Fallback to using dnsmasq.leases if no match found + if [ $found -ne 1 ]; then clientname=$(echo "$dhcpleases" | grep -i "$lookup_mac" | awk '{print $4}') 2>/dev/null if [ -z "$clientname" ] || [ "$clientname" == "*" ]; then clientname="UNKNOWN" fi fi + if [ -n "$paddedclientip" ] && [ "$paddedclientip" != "000.000.000.000" ]; then - # Check if this MAC address has already been processed if grep -q "$macupper" /jffs/addons/rtrmon.d/processed_vlanclients.txt && [ "$conntime" = "STALE" ]; then - continue # Skip processing this MAC address + continue else - # Mark this MAC as processed by adding it to the processed_macs_file echo "$macupper" >> /jffs/addons/rtrmon.d/processed_vlanclients.txt fi - #delete entry from temparp table sed -i -e '/'$clientmac'/d' /jffs/addons/rtrmon.d/temparp.txt if [ "$conntime" = "AiMesh" ]; then echo "$clientname,$paddedclientip,$macupper,$conntime" >> /jffs/addons/rtrmon.d/vlanclients$iface.txt @@ -5354,7 +5468,6 @@ attachedvlanclients() { if [ $vlansfound -eq 0 ]; then sort -f -d -t ',' -k "$SortbyNum" -k 4,4 /jffs/addons/rtrmon.d/vlanclients$iface.txt 2>/dev/null | \ awk -F',' -v OFS=',' '{if ($4 ~ /AiMesh/) {a[i++]=$0} else {print $0}} END {for (j=0; j /tmp/vlanclients_sorted.txt - # Move sorted file back to original mv /tmp/vlanclients_sorted.txt /jffs/addons/rtrmon.d/vlanclients$iface.txt column -t -s',' -o' | ' -N Name,IP,MAC,Uptime,"TX GB","RX GB","TX Mbps","RX Mbps","Sig" /jffs/addons/rtrmon.d/vlanclients$iface.txt | sed 's/^/ /' else @@ -5365,17 +5478,20 @@ attachedvlanclients() { fi } + # ------------------------------------------------------------------------------------------------------------------------- # attachedlanclients pulls connected client info from wl, arp and nvram +# attachedlanclients pulls connected client info from wl, arp and nvram attachedlanclients () { maxclientcount=$(cat /jffs/addons/rtrmon.d/temparp.txt | wc -l) rm -f /jffs/addons/rtrmon.d/clientlistbr0.txt dhcpleases="$(read_all_dhcp_leases)" - #find matchine client name - local clients=$(nvram get custom_clientlist) - local maxextractcount=$(echo "$clients" | awk -F'>>' '{count=0; for (i=1; i<=NF; i++) if ($i != "") count++; print count}') + local clients + clients="$(nvram get custom_clientlist)" + local maxextractcount + maxextractcount=$(echo "$clients" | awk -F'<' '{print NF}') local clientcount=0 while [ $clientcount -le $maxclientcount ] @@ -5391,40 +5507,39 @@ attachedlanclients () local macupper=$(echo "$clientmac" | tr 'a-f' 'A-F') - # Add the check for already processed clients - if grep -qi "$clients" /jffs/addons/rtrmon.d/processed_clients.txt; then - # Skip processing if the device was already handled + if grep -qi "$macupper" /jffs/addons/rtrmon.d/processed_clients.txt 2>/dev/null; then continue else echo "$macupper" >> /jffs/addons/rtrmon.d/processed_clients.txt fi - local counter=0 + local counter=2 local found=0 while [ $counter -le $maxextractcount ] do - counter=$((counter+1)) - local clientextract="$(echo $clients | cut -d "<" -f$counter | cut -d ">" -f1,2)" + local clientextract + clientextract="$(echo "$clients" | cut -d "<" -f"$counter" | cut -d ">" -f1,2)" - if [ -z "$clientextract" ]; then - continue - fi + [ -z "$clientextract" ] && { counter=$((counter+1)); continue; } - #clientip=$(cat /proc/net/arp | grep $clientmac | awk '{print $1}') clientip=$(cat /jffs/addons/rtrmon.d/temparp.txt | grep $clientmac | awk '{print $1; exit}') 2>/dev/null paddedclientip=$(echo "${clientip}" | grep -o -E '([0-9]*\.|[0-9]*)' | awk '{printf( "%03d\n", $1)}' | tr '\n' '.' | sed 's/.$//') 2>/dev/null - if [ -z $paddedclientip ]; then paddedclientip="000.000.000.000"; fi + if [ -z "$paddedclientip" ]; then paddedclientip="000.000.000.000"; fi - local client="$(echo $clientextract | awk -F ">" '{print $1}')" - local mac="$(echo $clientextract | awk -F ">" '{print $2}')" + local client + local mac + client="$(echo "$clientextract" | awk -F ">" '{print $1}')" + mac="$(echo "$clientextract" | awk -F ">" '{print $2}')" - if [ "$mac" == "$macupper" ]; then - clientname=$client + if [ "$mac" = "$macupper" ]; then + clientname="$client" found=1 break fi + + counter=$((counter+1)) done - # Fallback to using dnsmasq.leases if no match found + if [ $found -ne 1 ]; then clientname=$(echo "$dhcpleases" | grep -i "$clientmac" | awk '{print $4}') if [ -z "$clientname" ] || [ "$clientname" == "*" ]; then @@ -5464,8 +5579,12 @@ GetVPNWGIPCITY() NVRAMVPN1IP=$(ping -c 1 -w 1 $NVRAMVPN1ADDR | awk -F '[()]' '/PING/ { print $2}') if [ "$NVRAMVPN1ADDR" != "$oldvpn1ADDR" ]; then - oldvpn1ip=$(curl --silent --fail --interface $TUN1 --request GET --url https://ipv4.icanhazip.com) - if [ -z $oldvpn1ip ]; then oldvpn1ip=$NVRAMVPN1IP; fi + if [ "$VPNSite2Site" == "1" ]; then + oldvpn1ip=$NVRAMVPN1IP + else + oldvpn1ip=$(curl --silent --fail --interface $TUN1 --request GET --url https://ipv4.icanhazip.com) + if [ -z $oldvpn1ip ]; then oldvpn1ip=$NVRAMVPN1IP; fi + fi oldvpn1ADDR=$NVRAMVPN1ADDR fi @@ -5497,8 +5616,12 @@ GetVPNWGIPCITY() NVRAMVPN2IP=$(ping -c 1 -w 1 $NVRAMVPN2ADDR | awk -F '[()]' '/PING/ { print $2}') if [ "$NVRAMVPN2ADDR" != "$oldvpn2ADDR" ]; then - oldvpn2ip=$(curl --silent --fail --interface $TUN2 --request GET --url https://ipv4.icanhazip.com) - if [ -z $oldvpn2ip ]; then oldvpn2ip=$NVRAMVPN2IP; fi + if [ "$VPNSite2Site" == "1" ]; then + oldvpn2ip=$NVRAMVPN2IP + else + oldvpn2ip=$(curl --silent --fail --interface $TUN2 --request GET --url https://ipv4.icanhazip.com) + if [ -z $oldvpn2ip ]; then oldvpn2ip=$NVRAMVPN2IP; fi + fi oldvpn2ADDR=$NVRAMVPN2ADDR fi @@ -5530,8 +5653,12 @@ GetVPNWGIPCITY() NVRAMVPN3IP=$(ping -c 1 -w 1 $NVRAMVPN3ADDR | awk -F '[()]' '/PING/ { print $2}') if [ "$NVRAMVPN3ADDR" != "$oldvpn3ADDR" ]; then - oldvpn3ip=$(curl --silent --fail --interface $TUN3 --request GET --url https://ipv4.icanhazip.com) - if [ -z $oldvpn3ip ]; then oldvpn3ip=$NVRAMVPN3IP; fi + if [ "$VPNSite2Site" == "1" ]; then + oldvpn3ip=$NVRAMVPN3IP + else + oldvpn3ip=$(curl --silent --fail --interface $TUN3 --request GET --url https://ipv4.icanhazip.com) + if [ -z $oldvpn3ip ]; then oldvpn3ip=$NVRAMVPN3IP; fi + fi oldvpn3ADDR=$NVRAMVPN3ADDR fi @@ -5563,8 +5690,12 @@ GetVPNWGIPCITY() NVRAMVPN4IP=$(ping -c 1 -w 1 $NVRAMVPN4ADDR | awk -F '[()]' '/PING/ { print $2}') if [ "$NVRAMVPN4ADDR" != "$oldvpn4ADDR" ]; then - oldvpn4ip=$(curl --silent --fail --interface $TUN4 --request GET --url https://ipv4.icanhazip.com) - if [ -z $oldvpn4ip ]; then oldvpn4ip=$NVRAMVPN4IP; fi + if [ "$VPNSite2Site" == "1" ]; then + oldvpn4ip=$NVRAMVPN4IP + else + oldvpn4ip=$(curl --silent --fail --interface $TUN4 --request GET --url https://ipv4.icanhazip.com) + if [ -z $oldvpn4ip ]; then oldvpn4ip=$NVRAMVPN4IP; fi + fi oldvpn4ADDR=$NVRAMVPN4ADDR fi @@ -5596,8 +5727,12 @@ GetVPNWGIPCITY() NVRAMVPN5IP=$(ping -c 1 -w 1 $NVRAMVPN5ADDR | awk -F '[()]' '/PING/ { print $2}') if [ "$NVRAMVPN5ADDR" != "$oldvpn5ADDR" ]; then - oldvpn5ip=$(curl --silent --fail --interface $TUN5 --request GET --url https://ipv4.icanhazip.com) - if [ -z $oldvpn5ip ]; then oldvpn5ip=$NVRAMVPN5IP; fi + if [ "$VPNSite2Site" == "1" ]; then + oldvpn5ip=$NVRAMVPN5IP + else + oldvpn5ip=$(curl --silent --fail --interface $TUN5 --request GET --url https://ipv4.icanhazip.com) + if [ -z $oldvpn5ip ]; then oldvpn5ip=$NVRAMVPN5IP; fi + fi oldvpn5ADDR=$NVRAMVPN5ADDR fi @@ -5631,11 +5766,15 @@ GetVPNWGIPCITY() if [ "$WG1ADDR" != "$oldwg1ADDR" ] || [ "$wg1ip" = "0.0.0.0" ]; then # Added based on suggestion from @ZebMcKayhan ip rule add from $WGTUN1_IP lookup $WGTUN1 prio 10 >/dev/null 2>&1 - oldwg1ip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN1" --request GET --url https://ipv4.icanhazip.com" - oldwg1ip="$(eval $oldwg1ip)" - if [ -z "$oldwg1ip" ] || echo "$oldwg1ip" | grep -qoE 'Internet|traffic|Error|error' - then + if [ "$VPNSite2Site" == "1" ]; then oldwg1ip="$NVRAMWG1IP" + else + oldwg1ip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN1" --request GET --url https://ipv4.icanhazip.com" + oldwg1ip="$(eval $oldwg1ip)" + if [ -z "$oldwg1ip" ] || echo "$oldwg1ip" | grep -qoE 'Internet|traffic|Error|error' + then + oldwg1ip="$NVRAMWG1IP" + fi fi oldwg1ADDR=$WG1ADDR # Added based on suggestion from @ZebMcKayhan @@ -5672,11 +5811,15 @@ GetVPNWGIPCITY() if [ "$WG2ADDR" != "$oldwg2ADDR" ] || [ "$wg2ip" = "0.0.0.0" ]; then # Added based on suggestion from @ZebMcKayhan ip rule add from $WGTUN2_IP lookup $WGTUN2 prio 10 >/dev/null 2>&1 - oldwg2ip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN2" --request GET --url https://ipv4.icanhazip.com" - oldwg2ip="$(eval $oldwg2ip)" - if [ -z "$oldwg2ip" ] || echo "$oldwg2ip" | grep -qoE 'Internet|traffic|Error|error' - then + if [ "$VPNSite2Site" == "1" ]; then oldwg2ip="$NVRAMWG2IP" + else + oldwg2ip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN2" --request GET --url https://ipv4.icanhazip.com" + oldwg2ip="$(eval $oldwg2ip)" + if [ -z "$oldwg2ip" ] || echo "$oldwg2ip" | grep -qoE 'Internet|traffic|Error|error' + then + oldwg2ip="$NVRAMWG2IP" + fi fi oldwg2ADDR=$WG2ADDR # Added based on suggestion from @ZebMcKayhan @@ -5713,11 +5856,15 @@ GetVPNWGIPCITY() if [ "$WG3ADDR" != "$oldwg3ADDR" ] || [ "$wg3ip" = "0.0.0.0" ]; then # Added based on suggestion from @ZebMcKayhan ip rule add from $WGTUN3_IP lookup $WGTUN3 prio 10 >/dev/null 2>&1 - oldwg3ip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN3" --request GET --url https://ipv4.icanhazip.com" - oldwg3ip="$(eval $oldwg3ip)" - if [ -z "$oldwg3ip" ] || echo "$oldwg3ip" | grep -qoE 'Internet|traffic|Error|error' - then + if [ "$VPNSite2Site" == "1" ]; then oldwg3ip="$NVRAMWG3IP" + else + oldwg3ip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN3" --request GET --url https://ipv4.icanhazip.com" + oldwg3ip="$(eval $oldwg3ip)" + if [ -z "$oldwg3ip" ] || echo "$oldwg3ip" | grep -qoE 'Internet|traffic|Error|error' + then + oldwg3ip="$NVRAMWG3IP" + fi fi oldwg3ADDR=$WG3ADDR # Added based on suggestion from @ZebMcKayhan @@ -5754,11 +5901,15 @@ GetVPNWGIPCITY() if [ "$WG4ADDR" != "$oldwg4ADDR" ] || [ "$wg4ip" = "0.0.0.0" ]; then # Added based on suggestion from @ZebMcKayhan ip rule add from $WGTUN4_IP lookup $WGTUN4 prio 10 >/dev/null 2>&1 - oldwg4ip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN4" --request GET --url https://ipv4.icanhazip.com" - oldwg4ip="$(eval $oldwg4ip)" - if [ -z "$oldwg4ip" ] || echo "$oldwg4ip" | grep -qoE 'Internet|traffic|Error|error' - then + if [ "$VPNSite2Site" == "1" ]; then oldwg4ip="$NVRAMWG4IP" + else + oldwg4ip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN4" --request GET --url https://ipv4.icanhazip.com" + oldwg4ip="$(eval $oldwg4ip)" + if [ -z "$oldwg4ip" ] || echo "$oldwg4ip" | grep -qoE 'Internet|traffic|Error|error' + then + oldwg4ip="$NVRAMWG4IP" + fi fi oldwg4ADDR=$WG4ADDR # Added based on suggestion from @ZebMcKayhan @@ -5795,11 +5946,15 @@ GetVPNWGIPCITY() if [ "$WG5ADDR" != "$oldwg5ADDR" ] || [ "$wg5ip" = "0.0.0.0" ]; then # Added based on suggestion from @ZebMcKayhan ip rule add from $WGTUN5_IP lookup $WGTUN5 prio 10 >/dev/null 2>&1 - oldwg5ip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN5" --request GET --url https://ipv4.icanhazip.com" - oldwg5ip="$(eval $oldwg5ip)" - if [ -z "$oldwg5ip" ] || echo "$oldwg5ip" | grep -qoE 'Internet|traffic|Error|error' - then - oldwg5ip="$NVRAMWG5IP" + if [ "$VPNSite2Site" == "1" ]; then + oldwg2ip="$NVRAMWG2IP" + else + oldwg5ip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN5" --request GET --url https://ipv4.icanhazip.com" + oldwg5ip="$(eval $oldwg5ip)" + if [ -z "$oldwg5ip" ] || echo "$oldwg5ip" | grep -qoE 'Internet|traffic|Error|error' + then + oldwg5ip="$NVRAMWG5IP" + fi fi oldwg5ADDR=$WG5ADDR # Added based on suggestion from @ZebMcKayhan From 36719e4f2d8ea490e3c05ae8c3279bbb1ba6dd0c Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Thu, 4 Dec 2025 19:22:59 -0500 Subject: [PATCH 03/62] Rename rtrmon-2.2.2.sh to archive/rtrmon-2.2.2.sh --- rtrmon-2.2.2.sh => archive/rtrmon-2.2.2.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename rtrmon-2.2.2.sh => archive/rtrmon-2.2.2.sh (100%) diff --git a/rtrmon-2.2.2.sh b/archive/rtrmon-2.2.2.sh similarity index 100% rename from rtrmon-2.2.2.sh rename to archive/rtrmon-2.2.2.sh From d7412a55664eb616145ad8455e9970ed22215c29 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Thu, 4 Dec 2025 19:23:39 -0500 Subject: [PATCH 04/62] Delete rtrmon-debug.sh --- rtrmon-debug.sh | 6631 ----------------------------------------------- 1 file changed, 6631 deletions(-) delete mode 100644 rtrmon-debug.sh diff --git a/rtrmon-debug.sh b/rtrmon-debug.sh deleted file mode 100644 index 9f0f65f..0000000 --- a/rtrmon-debug.sh +++ /dev/null @@ -1,6631 +0,0 @@ -#!/bin/sh - -# RTRMON - Asus-Merlin Router Monitor by Viktor Jaep, 2022-2025 -# -# RTRMON is a shell script that provides near-realtime stats about your Asus-Merlin firmware router. Instead of having to -# find this information on various different screens or apps, this tool was built to bring all this info together in one -# stat dashboard. Having a 'system' dashboard showing current CPU, Memory, Disk and Network stats would compiment other -# dashboard-like scripts greatly (like RTRMON), sitting side-by-side in their own SSH windows to give you everything -# you need to know that's happening on your network with a glance at your screen. -# -# Capabilities have been added to give a full view of your router's CPU, Memory, Disk, NVRAM, Swap file, WAN, LAN, Wi-FI, -# IP4/6 addresses, CPU/Antenna Temps, in addition to having incorporated the Ookla Speedtest Binaries for you to run an on -# -demand Speedtest with the press of a button. New supported models are continually being added as @RMerlin adds support -# for them with his own firmware. -# -# Please use the 'sh rtrmon.sh -setup' command to configure the necessary parameters that match your environment the best! -# -# Last Modified: 2025-Nov-16 -########################################################################################################################### - -#Preferred standard router binaries path -export PATH="/sbin:/bin:/usr/sbin:/usr/bin:$PATH" - -# ------------------------------------------------------------------------------------------------------------------------- -# System Variables (Do not change beyond this point or this may change the programs ability to function correctly) -# ------------------------------------------------------------------------------------------------------------------------- -Version="2.2.3" -Beta=0 -ScreenshotMode=0 -LOGFILE="/jffs/addons/rtrmon.d/rtrmon.log" # Logfile path/name that captures important date/time events - change -APPPATH="/jffs/scripts/rtrmon.sh" # Path to the location of rtrmon.sh -CFGPATH="/jffs/addons/rtrmon.d/rtrmon.cfg" # Path to the location of rtrmon.cfg -DLVERPATH="/jffs/addons/rtrmon.d/version.txt" # Path to downloaded version from the source repository -OOKLAPATH="/jffs/addons/rtrmon.d/speedtest" # Path to Ookla speedtest binary -SPDRESPATH="/jffs/addons/rtrmon.d/results.txt" # Path to latest speedtest results -IFLIST="/jffs/addons/rtrmon.d/interfaces.txt" # Path to the Interface List -DIAGRESPATH="/jffs/addons/rtrmon.d/diagres.txt" # Path to the network diagnostics results -NMAPWANRESPATH="/jffs/addons/rtrmon.d/nwanres.txt" # Path to the nmap WAN open TCP port results -NMAPLANRESPATH="/jffs/addons/rtrmon.d/nlanres.txt" # Path to the nmap LAN open TCP port results -NMAPUWANRESPATH="/jffs/addons/rtrmon.d/nuwanres.txt" # Path to the nmap WAN open UDP port results -NMAPULANRESPATH="/jffs/addons/rtrmon.d/nulanres.txt" # Path to the nmap LAN open UDP port results -INITIALBOOT=0 -CHANGES=0 -LOGSIZE=2000 -Interval=10 -MaxSpeedInet=1000 -MaxSpeedInetUL=50 -MaxSpeedLAN=1000 -MaxSpeed24Ghz=450 -MaxSpeed5Ghz=780 -MaxSpeed6Ghz=920 -TempUnits="C" -Speedtst=0 -WANOverride="Auto" -WAN0AltModes=0 -VPNSite2Site=0 -PSView="TCP" -NCView="WAN" -spdtestsvrID=0 -autorotate=0 -autorotateindicator="OFF" -QueueSpdTest=0 -QueueNetworkDiag=0 -QueueNetworkConn=0 -QueueVPNSlot1=0 -QueueVPNSlot2=0 -QueueVPNSlot3=0 -QueueVPNSlot4=0 -QueueVPNSlot5=0 -QueueWGlot1=0 -QueueWGSlot2=0 -QueueWGSlot3=0 -QueueWGSlot4=0 -QueueWGSlot5=0 -vpn1slot=0 -vpn2slot=0 -vpn3slot=0 -vpn4slot=0 -vpn5slot=0 -VPNState=0 -VPN2State=0 -VPN3State=0 -VPN4State=0 -VPN5State=0 -vpn1city="Unknown" -vpn2city="Unknown" -vpn3city="Unknown" -vpn4city="Unknown" -vpn5city="Unknown" -vpn1ip="0.0.0.0" -vpn2ip="0.0.0.0" -vpn3ip="0.0.0.0" -vpn4ip="0.0.0.0" -vpn5ip="0.0.0.0" -vpn1on="False" -vpn2on="False" -vpn3on="False" -vpn4on="False" -vpn5on="False" -wg1on="False" -wg2on="False" -wg3on="False" -wg4on="False" -wg5on="False" -FromUI=0 -NextPage=1 -memused1=0 -memfree1=0 -memshrd1=0 -membuff1=0 -memcach1=0 -memused2=0 -memfree2=0 -memshrd2=0 -membuff2=0 -memcach2=0 -cpuusr1=0 -cpusys1=0 -cpunice1=0 -cpuidle1=0 -cpuirq1=0 -displaycpuusr1=0 -displaycpusys1=0 -displaycpunice1=0 -displaycpuidle1=0 -displaycpuirq1=0 -w24udsched="Scheduler Inactive" -w5udsched="Scheduler Inactive" -w52udsched="Scheduler Inactive" -w6udsched="Scheduler Inactive" -w62udsched="Scheduler Inactive" -w24updown="UP" -w5updown="UP" -w52updown="UP" -w6updown="UP" -w62updown="UP" -SortbyOpt="Name" - -##-------------------------------------## -## Added by Martinski W. [2024-Nov-04] ## -##-------------------------------------## -timerReset=0 -timeoutcmd="" # For "timeout" cmd for "nvram" calls # -timeoutsec="" # For "timeout" cmd for "nvram" calls # -timeoutlng="" # For "timeout" cmd for "nvram" calls # -hideoptions=1 # Hide/Show menu options flag # -prevHideOpts=X # Avoid redisplaying the options menu unnecessarily too often # -prevSortByOpt=X # Avoid resetting the timer loop unnecessarily too often # -bootInterval=10 # For "Boot Sequence" loop # -LAN_HostName="" -readonly gSavedSTTY="$(stty -g)" - -##-------------------------------------## -## Added by Martinski W. [2024-Nov-05] ## -##-------------------------------------## -pausedTimerEnabled=false # To pause/resume main loop timer cycle # -pausedTimerDispStr="" -readonly pausedTimerMsgStr=" [** PAUSED **] " -readonly pausedTimerMsgLen="${#pausedTimerMsgStr}" - -# Color variables -CBlack="\e[1;30m" -InvBlack="\e[1;40m" -CRed="\e[1;31m" -InvRed="\e[1;41m" -CGreen="\e[1;32m" -InvGreen="\e[1;42m" -CDkGray="\e[1;90m" -InvDkGray="\e[1;100m" -InvLtGray="\e[1;47m" -CYellow="\e[1;33m" -InvYellow="\e[1;43m" -CBlue="\e[1;34m" -InvBlue="\e[1;44m" -CMagenta="\e[1;35m" -CCyan="\e[1;36m" -InvCyan="\e[1;46m" -CWhite="\e[1;37m" -InvWhite="\e[1;107m" -CClear="\e[0m" - -# ------------------------------------------------------------------------------------------------------------------------- -# Functions -# ------------------------------------------------------------------------------------------------------------------------- - -#Shows the version bar formatted for build and date/time with TZ spacing# -##----------------------------------------## -## Modified by Martinski W. [2024-Nov-04] ## -##----------------------------------------## -showheader() -{ - if [ "$hideoptions" = "0" ] && [ "$hideoptions" != "$prevHideOpts" ] - then displayopsmenu ; fi - - timerReset=0 - prevHideOpts="$hideoptions" - prevSortByOpt="$SortbyOpt" - - tzone="$(date +%Z)" - tzonechars="${#tzone}" - - if [ "$tzonechars" = "1" ]; then tzspaces=" "; - elif [ "$tzonechars" = "2" ]; then tzspaces=" "; - elif [ "$tzonechars" = "3" ]; then tzspaces=" "; - elif [ "$tzonechars" = "4" ]; then tzspaces=" "; - elif [ "$tzonechars" = "5" ]; then tzspaces=" "; fi - - #Display RTRMON client header - echo -en "${InvGreen} ${InvDkGray}${CWhite} RTRMON - v" - printf "%-8s" $Version - echo -e " ${CGreen}(S)${CWhite}how/${CGreen}(H)${CWhite}ide Operations Menu ${InvDkGray} $tzspaces$(date) ${CClear}" -} - -# ------------------------------------------------------------------------------------------------------------------------- -# Displays the "Operations Menu" on top of screen. - -##----------------------------------------## -## Modified by Martinski W. [2024-Nov-02] ## -##----------------------------------------## -displayopsmenu() -{ - amtmdisp="${CDkGray}[n/a] " - - echo -e "${InvGreen} ${InvDkGray}${CWhite} Operations Menu ${CClear}" - if [ "$vpn1on" == "True" ] || [ "$vpn2on" == "True" ] || [ "$vpn3on" == "True" ] || [ "$vpn4on" == "True" ] || [ "$vpn5on" == "True" ] - then - echo -e "${InvGreen} ${CClear} Speedtest ${CGreen}(I)${CClear} WAN / VPN 1:${CGreen}(1)${CClear} 2:${CGreen}(2)${CClear} 3:${CGreen}(3)${CClear} 4:${CGreen}(4)${CClear} 5:${CGreen}(5)${CClear} ${InvGreen} ${CClear} ${CGreen}(M)${CClear}ain Setup Menu / Configuration Menu${CClear}" - else - echo -e "${InvGreen} ${CClear} Speedtest ${CGreen}(I)${CClear} WAN ${CDkGray}/ VPN 1:(1) 2:(2) 3:(3) 4:(4) 5:(5)${CClear} ${InvGreen} ${CClear} ${CGreen}(M)${CClear}ain Setup Menu / Configuration Menu${CClear}" - fi - if [ "$wg1on" == "True" ] || [ "$wg2on" == "True" ] || [ "$wg3on" == "True" ] || [ "$wg4on" == "True" ] || [ "$wg5on" == "True" ] - then - echo -e "${InvGreen} ${CClear} Speedtest Wireguard 1:${CGreen}(6)${CClear} 2:${CGreen}(7)${CClear} 3:${CGreen}(8)${CClear} 4:${CGreen}(9)${CClear} 5:${CGreen}(0)${CClear} ${InvGreen} ${CClear} L${CGreen}(O)${CClear}g Viewer / Trim Log Size (rows): ${CGreen}$LOGSIZE${CClear}" - else - echo -e "${InvGreen} ${CClear} ${CDkGray}Speedtest Wireguard 1:(6) 2:(7) 3:(8) 4:(9) 5:(0)${CClear} ${InvGreen} ${CClear} L${CGreen}(O)${CClear}g Viewer / Trim Log Size (rows): ${CGreen}$LOGSIZE${CClear}" - fi - echo -e "${InvGreen} ${CClear} Run Router Network ${CGreen}(D)${CClear}iagnostics ${InvGreen} ${CClear} ${CGreen}(N)${CClear}ext Page / ${CGreen}(P)${CClear}revious Page: ${CGreen}($NextPage/7)${CClear}" - echo -e "${InvGreen} ${CClear} Refresh ${CGreen}(C)${CClear}urrent Network Statistics ${InvGreen} ${CClear} Auto ${CGreen}(R)${CClear}otate Pages Option: ${CGreen}$autorotateindicator${CClear}" - echo -e "${InvGreen} ${CClear} View ${CGreen}(W)${CClear}AN / ${CGreen}(L)${CClear}AN / ${CGreen}(V)${CClear}PN / W${CGreen}(G)${CClear} Stats ${InvGreen} ${CClear} Router Model/FW: ${CGreen}${RouterModel} | ${FWBUILD}${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" - echo "" -} - -##-------------------------------------## -## Added by Martinski W. [2024-Nov-02] ## -##-------------------------------------## -_ConsumeKeypressBuffer_() -{ - local savedSettings - local keyPress='' prevTimeSec - savedSettings="$(stty -g)" - prevTimeSec="$(date +%s)" - read -rs -n1000 -t 1 keyPress < "$(tty 0>&2)" - while [ "$(date +%s)" -lt "$((prevTimeSec + 1))" ] - do - stty -echo -icanon min 0 time 1 - cat - > /dev/null - done - stty "$savedSettings" -} - -##-------------------------------------## -## Added by Martinski W. [2024-Nov-02] ## -##-------------------------------------## -_IgnoreKeypresses_() -{ - if [ $# -eq 0 ] || [ -z "$1" ] - then return 1 ; fi - case "$1" in - ON) stty -echo ;; - OFF) stty "$gSavedSTTY" ; stty echo ;; - esac -} - -# ------------------------------------------------------------------------------------------------------------------------- -# LogoNM displays the RTRMON script name in a cool ASCII font that fades in -##----------------------------------------## -## Modified by Martinski W. [2024-Nov-02] ## -##----------------------------------------## -logoNM () -{ - clear - echo "" - echo "" - echo "" - echo -e "${CDkGray} ____ __________ __ _______ _ __" - echo -e " / __ \/_ __/ __ \/ |/ / __ \/ | / /" - echo -e " / /_/ / / / / /_/ / /|_/ / / / / |/ /" - echo -e " / _, _/ / / / _, _/ / / / /_/ / /| /" - echo -e " /_/ |_| /_/ /_/ |_/_/ /_/\____/_/ |_/ v$Version" - echo "" - echo "" - printf "\r ${CGreen} [ INITIALIZING ] ${CClear}" - _ConsumeKeypressBuffer_ - clear - echo "" - echo "" - echo "" - echo -e "${CYellow} ____ __________ __ _______ _ __" - echo -e " / __ \/_ __/ __ \/ |/ / __ \/ | / /" - echo -e " / /_/ / / / / /_/ / /|_/ / / / / |/ /" - echo -e " / _, _/ / / / _, _/ / / / /_/ / /| /" - echo -e " /_/ |_| /_/ /_/ |_/_/ /_/\____/_/ |_/ v$Version" - echo "" - echo "" -} - -# ------------------------------------------------------------------------------------------------------------------------- -# logoNMexit displays the RTRMON script name in a cool ASCII font that fades out - -logoNMexit () { - clear - echo "" - echo "" - echo "" - echo -e "${CYellow} ____ __________ __ _______ _ __" - echo -e " / __ \/_ __/ __ \/ |/ / __ \/ | / /" - echo -e " / /_/ / / / / /_/ / /|_/ / / / / |/ /" - echo -e " / _, _/ / / / _, _/ / / / /_/ / /| /" - echo -e " /_/ |_| /_/ /_/ |_/_/ /_/\____/_/ |_/ v$Version" - echo "" - echo "" - printf "\r ${CGreen} [ SHUTTING DOWN ] ${CClear}" - sleep 1 - clear - echo "" - echo "" - echo "" - echo -e "${CDkGray} ____ __________ __ _______ _ __" - echo -e " / __ \/_ __/ __ \/ |/ / __ \/ | / /" - echo -e " / /_/ / / / / /_/ / /|_/ / / / / |/ /" - echo -e " / _, _/ / / / _, _/ / / / /_/ / /| /" - echo -e " /_/ |_| /_/ /_/ |_/_/ /_/\____/_/ |_/ v$Version" - echo "" - echo "" - printf "\r ${CGreen} [ SHUTTING DOWN ] ${CClear}" - sleep 1 - printf "\r ${CDkGray} [ GOODBYE... ] ${CClear}\n\n" - sleep 1 -} - -##-------------------------------------## -## Added by Martinski W. [2024-Nov-02] ## -##-------------------------------------## -_PressAnyKeyToContinue_() -{ printf "\nPress any key to continue..." ; read -rsn1 anykey ; echo ; } - -# ------------------------------------------------------------------------------------------------------------------------- -# promptyn takes input for Y/N questions - -promptyn () { # No defaults, just y or n - while true; do - read -p '[y/n]? ' YESNO - case "$YESNO" in - [Yy]* ) return 0 ;; - [Nn]* ) return 1 ;; - * ) echo -e "\nPlease answer y or n.";; - esac - done -} - -# ------------------------------------------------------------------------------------------------------------------------- -# Spinner provides a small spinning indicator on the screen to show script activity - -spinner() -{ - spins="$1" - - spin=0 - totalspins="$((spins / 4))" - while [ "$spin" -le "$totalspins" ] - do - for spinchar in / - \\ \| - do - printf "\r$spinchar" - sleep 1 - done - spin="$((spin+1))" - done - - printf "\r" -} - -# ------------------------------------------------------------------------------------------------------------------------- -# Preparebar and Progressbar is a script that provides a nice progressbar to show script activity and bar charts -##----------------------------------------## -## Modified by Martinski W. [2024-Nov-02] ## -##----------------------------------------## -preparebar() -{ - # $1 - bar length - # $2 - bar char - barlen="$1" - barspaces="$(printf "%*s" "$1" ' ')" - barchars="$(printf "%*s" "$1" ' ' | tr ' ' "$2")" -} - -##----------------------------------------## -## Modified by Martinski W. [2024-Nov-02] ## -##----------------------------------------## -# Had to make some mods to the variables being passed, and created an inverse colored progress bar -progressbar() -{ - # $1 - number (-1 for clearing the bar) - # $2 - max number - # $3 - system name - # $4 - measurement - # $5 - standard/reverse progressbar - # $6 - alternate display values - # $7 - alternate value for progressbar exceeding 100% - - insertspc=" " - - if [ "$1" -eq -1 ] - then - printf "\r $barspaces\r" - else - if [ $# -gt 6 ] && [ -n "$7" ] && [ "$1" -ge "$7" ] - then - barch="$(($7*barlen/$2))" - barsp="$((barlen-barch))" - progr="$((100*$1/$2))" - else - barch="$(($1*barlen/$2))" - barsp="$((barlen-barch))" - progr="$((100*$1/$2))" - fi - - if [ $# -gt 5 ] && [ -n "$6" ]; then AltNum="$6" ; else AltNum="$1" ; fi - - if [ "$5" = "Standard" ] - then - if [ "$progr" -le 60 ]; then - printf "${InvGreen}${CWhite}$insertspc${CClear}${CWhite}${3} ${CDkGray}[${CGreen}%.${barch}s%.${barsp}s${CDkGray}]${CClear} ${CWhite}${InvDkGray}$AltNum ${4} / ${progr}%%\r${CClear}" "$barchars" "$barspaces" - elif [ "$progr" -gt 60 ] && [ "$progr" -le 85 ]; then - printf "${InvYellow}${CBlack}$insertspc${CClear}${CYellow}${3} ${CDkGray}[${CYellow}%.${barch}s%.${barsp}s${CDkGray}]${CClear} ${CWhite}${InvDkGray}$AltNum ${4} / ${progr}%%\r${CClear}" "$barchars" "$barspaces" - else - printf "${InvRed}${CWhite}$insertspc${CClear}${CRed}${3} ${CDkGray}[${CRed}%.${barch}s%.${barsp}s${CDkGray}]${CClear} ${CWhite}${InvDkGray}$AltNum ${4} / ${progr}%%\r${CClear}" "$barchars" "$barspaces" - fi - elif [ "$5" = "Reverse" ] - then - if [ "$progr" -le 15 ]; then - printf "${InvRed}${CWhite}$insertspc${CClear}${CRed}${3} ${CDkGray}[${CRed}%.${barch}s%.${barsp}s${CDkGray}]${CClear} ${CWhite}${InvDkGray}$AltNum ${4} / ${progr}%%\r${CClear}" "$barchars" "$barspaces" - elif [ "$progr" -gt 15 ] && [ "$progr" -le 40 ]; then - printf "${InvYellow}${CBlack}$insertspc${CClear}${CYellow}${3} ${CDkGray}[${CYellow}%.${barch}s%.${barsp}s${CDkGray}]${CClear} ${CWhite}${InvDkGray}$AltNum ${4} / ${progr}%%\r${CClear}" "$barchars" "$barspaces" - else - printf "${InvGreen}${CWhite}$insertspc${CClear}${CWhite}${3}${CGreen} ${CDkGray}[${CGreen}%.${barch}s%.${barsp}s${CDkGray}]${CClear} ${CWhite}${InvDkGray}$AltNum ${4} / ${progr}%%\r${CClear}" "$barchars" "$barspaces" - fi - elif [ "$5" = "CPU" ] - then - if [ "$progr" -le 80 ]; then - printf "${InvGreen}${CWhite}$insertspc${CClear}${CWhite}${3}${CGreen} ${CDkGray}[${CGreen}%.${barch}s%.${barsp}s${CDkGray}]${CClear} ${CWhite}${InvDkGray}$AltNum ${4} / ${progr}%%\r${CClear}" "$barchars" "$barspaces" - elif [ "$progr" -gt 80 ] && [ "$progr" -le 90 ]; then - printf "${InvYellow}${CBlack}$insertspc${CClear}${CYellow}${3} ${CDkGray}[${CYellow}%.${barch}s%.${barsp}s${CDkGray}]${CClear} ${CWhite}${InvDkGray}$AltNum ${4} / ${progr}%%\r${CClear}" "$barchars" "$barspaces" - else - printf "${InvRed}${CWhite}$insertspc${CClear}${CRed}${3} ${CDkGray}[${CRed}%.${barch}s%.${barsp}s${CDkGray}]${CClear} ${CWhite}${InvDkGray}$AltNum ${4} / ${progr}%%\r${CClear}" "$barchars" "$barspaces" - fi - fi - fi -} - -# ------------------------------------------------------------------------------------------------------------------------- -# Shows a more minimalistic progress bar that indicates seconds/% -##----------------------------------------## -## Modified by Martinski W. [2024-Nov-06] ## -##----------------------------------------## -progressbaroverride() -{ - # $1 - number (-1 for clearing the bar) - # $2 - max number - # $3 - system name - # $4 - measurement - # $5 - standard/reverse progressbar - # $6 - alternate display values - # $7 - alternate value for progressbar exceeding 100% - - local barch barsp percnt altNum readTimeSec - insertspc=" " - - _GetPercent_() { printf "%.1f" "$(echo "$1" | awk "{print $1}")" ; } - - _UpdateProgressBar_() - { - if [ "$2" = "Standard" ] && [ "$INITIALBOOT" -eq 0 ] - then - printf " ${CWhite}${InvDkGray}%3d${1} /%5.1f%%${CClear} [${CGreen}e${CClear}=Exit] [Selection? ${InvGreen} ${CClear}${CGreen}] ${pausedTimerDispStr} \r${CClear}" "$altNum" "$percnt" - elif [ "$2" = "Standard" ] && [ "$INITIALBOOT" -eq 1 ] - then - printf "${CDkGray} [${CGreen}%.${barch}s%.${barsp}s${CDkGray}] \r${CClear}" "$barchars" "$barspaces" - fi - } - - _PausedTimerHandler_() - { - local keyPress readTimeSec - while "$pausedTimerEnabled" - do - keyPress='' - readTimeSec="$(date +%s)" - read -rsn1 -t 1 keyPress < "$(tty 0>&2)" - if [ "$keyPress" = "X" ] - then - pausedTimerEnabled=false - pausedTimerDispStr="$(printf "%*s" "$pausedTimerMsgLen" ' ')" - break - fi - if [ "$(date +%s)" -lt "$((readTimeSec + 1))" ] - then - stty -icanon min 0 time 5 - cat - > /dev/null - fi - done - } - - if [ "$1" -eq -1 ] - then - printf "\r $barspaces\r" - else - if [ $# -gt 6 ] && [ -n "$7" ] && [ "$1" -ge "$7" ] - then - barch="$(($7*barlen/$2))" - barsp="$((barlen-barch))" - percnt="$(_GetPercent_ "(100*$1/$2)")" - else - barch="$(($1*barlen/$2))" - barsp="$((barlen-barch))" - percnt="$(_GetPercent_ "(100*$1/$2)")" - fi - - if [ $# -gt 5 ] && [ -n "$6" ]; then altNum="$6" ; else altNum="$1" ; fi - - _UpdateProgressBar_ "$4" "$5" - - if [ "$INITIALBOOT" = "0" ] - then - # Borrowed this wonderful keypress capturing mechanism from @Eibgrad... thank you! :) - readTimeSec="$(date +%s)" - key_press=''; read -rsn1 -t 1 key_press < "$(tty 0>&2)" - - if [ "$key_press" ] - then - case "$key_press" in - [Cc]) QueueNetworkConn=1 - echo -e "${CClear}[Queuing Network Connection Stats] "; - sleep 1; NextPage=6; timerReset=1 - ;; - [Dd]) QueueNetworkDiag=1 - echo -e "${CClear}[Queuing Network Diagnostics] "; - sleep 1; NextPage=5; timerReset=1 - ;; - [Ee]) clear; logoNMexit; echo -e "${CClear}"; exit 0 - ;; - [Gg]) NCView="WG"; NextPage=6; timerReset=1 - ;; - [Hh]) hideoptions=1 ; [ "$hideoptions" != "$prevHideOpts" ] && timerReset=1 - ;; - [Ii]) QueueSpdTest=1 - echo -e "${CClear}[Queuing WAN Speedtest] "; - sleep 1; NextPage=4; timerReset=1 - ;; - [Ll]) NCView="LAN"; NextPage=6; timerReset=1 - ;; - [Mm]) _IgnoreKeypresses_ OFF - FromUI=1; vsetup; source "$CFGPATH" - echo -e "\n${CClear}[Returning to the Main UI momentarily] "; - sleep 1; FromUI=0; timerReset=1 - ;; - [Nn]) timerReset=1 - if [ "$NextPage" = "1" ]; then NextPage=2 - elif [ "$NextPage" = "2" ]; then NextPage=3 - elif [ "$NextPage" = "3" ]; then NextPage=4 - elif [ "$NextPage" = "4" ]; then NextPage=5 - elif [ "$NextPage" = "5" ]; then NextPage=6 - elif [ "$NextPage" = "6" ]; then NextPage=7 - elif [ "$NextPage" = "7" ]; then NextPage=1 - fi - ;; - [Oo]) _IgnoreKeypresses_ OFF ; vlogs ;; - [Pp]) timerReset=1 - if [ "$NextPage" = "1" ]; then NextPage=7 - elif [ "$NextPage" = "2" ]; then NextPage=1 - elif [ "$NextPage" = "3" ]; then NextPage=2 - elif [ "$NextPage" = "4" ]; then NextPage=3 - elif [ "$NextPage" = "5" ]; then NextPage=4 - elif [ "$NextPage" = "6" ]; then NextPage=5 - elif [ "$NextPage" = "7" ]; then NextPage=6 - fi - ;; - [Rr]) if [ "$autorotate" = 0 ] - then autorotate=1; autorotateindicator="ON" - elif [ "$autorotate" = "1" ] - then autorotate=0; autorotateindicator="OFF" - fi - timerReset=1 - ;; - [Ss]) hideoptions=0 ; [ "$hideoptions" != "$prevHideOpts" ] && timerReset=1 - ;; - [Tt]) PSView="TCP"; NextPage=5; timerReset=1 - ;; - [Uu]) PSView="UDP"; NextPage=5; timerReset=1 - ;; - [Vv]) NCView="VPN"; NextPage=6; timerReset=1 - ;; - [Ww]) NCView="WAN"; NextPage=6; timerReset=1 - ;; - X) if "$pausedTimerEnabled" - then - pausedTimerEnabled=false - pausedTimerDispStr="$(printf "%*s" "$pausedTimerMsgLen" ' ')" - else - pausedTimerEnabled=true - pausedTimerDispStr="${CWhite}${InvRed}${pausedTimerMsgStr}${CClear}" - _UpdateProgressBar_ "$4" "$5" - _PausedTimerHandler_ - fi - ;; - 1) QueueVPNSlot1=1 - echo -e "${CClear}[Queuing VPN1 Speedtest] "; - sleep 1; NextPage=4; timerReset=1 - ;; - 2) QueueVPNSlot2=1 - echo -e "${CClear}[Queuing VPN2 Speedtest] "; - sleep 1; NextPage=4; timerReset=1 - ;; - 3) QueueVPNSlot3=1 - echo -e "${CClear}[Queuing VPN3 Speedtest] "; - sleep 1; NextPage=4; timerReset=1 - ;; - 4) QueueVPNSlot4=1 - echo -e "${CClear}[Queuing VPN4 Speedtest] "; - sleep 1; NextPage=4; timerReset=1 - ;; - 5) QueueVPNSlot5=1 - echo -e "${CClear}[Queuing VPN5 Speedtest] "; - sleep 1; NextPage=4; timerReset=1 - ;; - 6) QueueWGSlot1=1 - echo -e "${CClear}[Queuing WG1 Speedtest] "; - sleep 1; NextPage=4; timerReset=1 - ;; - 7) QueueWGSlot2=1 - echo -e "${CClear}[Queuing WG2 Speedtest] "; - sleep 1; NextPage=4; timerReset=1 - ;; - 8) QueueWGSlot3=1 - echo -e "${CClear}[Queuing WG3 Speedtest] "; - sleep 1; NextPage=4; timerReset=1 - ;; - 9) QueueWGSlot4=1 - echo -e "${CClear}[Queuing WG4 Speedtest] "; - sleep 1; NextPage=4; timerReset=1 - ;; - 0) QueueWGSlot5=1 - echo -e "${CClear}[Queuing WG5 Speedtest] "; - sleep 1; NextPage=4; timerReset=1 - ;; - - [\!]) SortbyOpt="Name"; [ "$SortbyOpt" != "$prevSortByOpt" ] && [ "$NextPage" = "7" ] && timerReset=1 ;; - [\@]) SortbyOpt="IP"; [ "$SortbyOpt" != "$prevSortByOpt" ] && [ "$NextPage" = "7" ] && timerReset=1 ;; - [\#]) SortbyOpt="MAC"; [ "$SortbyOpt" != "$prevSortByOpt" ] && [ "$NextPage" = "7" ] && timerReset=1 ;; - *) ;; ##IGNORE INVALID key presses ## - esac - _IgnoreKeypresses_ ON - if [ "$(date +%s)" -lt "$((readTimeSec + 1))" ] - then - stty -icanon min 0 time 1 - cat - > /dev/null - fi - fi - else - ## Initial Boot Sequence Loop ## - _ConsumeKeypressBuffer_ - fi - fi -} - -# ------------------------------------------------------------------------------------------------------------------------- -# converttemps converts temp readouts from C to F or K - -converttemps () { -# $1 is the incoming C Temp - - if [ "$TempUnits" == "F" ]; then - currenttemp=$(awk -v v1=$1 'BEGIN{printf "%0.2f\n", (v1*9)/5+32}' | cut -d . -f 1) - currentrange=212 - elif [ "$TempUnits" == "K" ]; then - currenttemp=$(awk -v v1=$1 'BEGIN{printf "%0.2f\n", v1+273}' | cut -d . -f 1) - currentrange=373 - elif [ "$TempUnits" == "C" ]; then - currenttemp=$1 - currentrange=100 - else - # Default to C if someone entered something other than C, F or K - TempUnits="C" - currenttemp=$1 - currentrange=100 - fi - -} - -# ------------------------------------------------------------------------------------------------------------------------- -# updatecheck downloads the latest update version file from github, and compares it with what's currently installed - -updatecheck () { - - # Download the latest version file from the source repository - curl --silent --retry 3 "https://raw.githubusercontent.com/ViktorJp/RTRMON/master/version.txt" -o "/jffs/addons/rtrmon.d/version.txt" - - if [ -f $DLVERPATH ] - then - # Read in its contents for the current version file - DLVersion=$(cat $DLVERPATH) - - # Compare the new version with the old version and log it - if [ "$Beta" == "1" ]; then # Check if Dev/Beta Mode is enabled and disable notification message - UpdateNotify=0 - elif [ "$DLVersion" != "$Version" ]; then - DLVersionPF=$(printf "%-8s" $DLVersion) - VersionPF=$(printf "%-8s" $Version) - UpdateNotify="${InvYellow} ${InvDkGray}${CWhite} Update available: v$VersionPF -> v$DLVersionPF ${CClear}" - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new update (v$DLVersion) is available to download" >> $LOGFILE - else - UpdateNotify=0 - fi - fi -} - -# ------------------------------------------------------------------------------------------------------------------------- -# calls the nano text editor to view the RTRMON log file - -vlogs() { - -export TERM=linux -nano +999999 --linenumbers $LOGFILE -timerReset=1 - -} - -# ------------------------------------------------------------------------------------------------------------------------- -# trimlogs will cut down log size (in rows) based on custom value - -trimlogs() -{ - - if [ "$LOGSIZE" -gt 0 ] - then - currlogsize=$(wc -l $LOGFILE | awk '{ print $1 }' ) # Determine the number of rows in the log - - if [ "$currlogsize" -gt "$LOGSIZE" ] # If it's bigger than the max allowed, tail/trim it! - then - echo "$(tail -$LOGSIZE $LOGFILE)" > $LOGFILE - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: Trimmed the log file down to $LOGSIZE lines" >> $LOGFILE - fi - - fi -} - -# ------------------------------------------------------------------------------------------------------------------------- -# vconfig guides you through the various configuration options for RTRMON -##----------------------------------------## -## Modified by Martinski W. [2024-Nov-02] ## -##----------------------------------------## -vconfig() -{ - _SetUpTimeoutCmdVars_ - - if [ -f "$CFGPATH" ] #Making sure file exists before proceeding - then - source "$CFGPATH" - - CHANGES=0 #track notification to save your changes# - - while true - do - clear - echo -e "${InvGreen} ${InvDkGray}${CWhite} RTRMON Configuration Options ${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} Please choose from the various options below, which allow you to modify certain${CClear}" - echo -e "${InvGreen} ${CClear} customizable parameters that affect the operation of this script.${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 1)${CClear} : Timer Interval (seconds) : ${CGreen}$Interval" - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 2)${CClear} : Max Internet Download Speed (Mbps) : ${CGreen}$MaxSpeedInet" - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 3)${CClear} : Max Internet Upload Speed (Mbps) : ${CGreen}$MaxSpeedInetUL" - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 4)${CClear} : Max LAN Speed (Mbps) : ${CGreen}$MaxSpeedLAN" - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 5)${CClear} : Max 2.4GHz Speed (Mbps) : ${CGreen}$MaxSpeed24Ghz" - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 6)${CClear} : Max 5GHz Speed (Mbps) : ${CGreen}$MaxSpeed5Ghz" - - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 7)${CClear} : Max 6GHz Speed (Mbps) : ${CGreen}$MaxSpeed6Ghz" - else - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 7)${CClear} : ${CDkGray}Max 6GHz Speed (Mbps) : N/A" - fi - - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 8)${CClear} : Temperature Units (C/F/K) : ${CGreen}$TempUnits" - - echo -en "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 9)${CClear} : Enable Ookla Speedtest? (Y/N) : ${CGreen}" - if [ "$Speedtst" = "0" ] - then printf "No\n" - else printf "Yes\n" - fi - - if [ "$spdtestsvrID" == "0" ] && [ "$Speedtst" == "1" ]; then - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(10)${CClear} : Custom Speedtest Server ID? : ${CGreen}Use Closest" - elif [ "$spdtestsvrID" != "0" ] && [ "$Speedtst" == "1" ]; then - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(10)${CClear} : Custom Speedtest Server ID? : ${CGreen}$spdtestsvrID" - else - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(10)${CClear} : Custom Speedtest Server ID? : ${CDkGray}N/A" - fi - - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(11)${CClear} : WAN0 Interface Override? : ${CGreen}$WANOverride" - - if [ "$WAN0AltModes" == "0" ]; then WAN0AltModesdisp="No"; else WAN0AltModesdisp="Yes"; fi - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(12)${CClear} : Mark Router As iMesh Node/Repeater/Bridge? : ${CGreen}$WAN0AltModesdisp" - if [ "$VPNSite2Site" == "0" ]; then VPNSite2Sitedisp="No"; else VPNSite2Sitedisp="Yes"; fi - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(13)${CClear} : Mark Router As VPN Site-To-Site Only? : ${CGreen}$VPNSite2Sitedisp" - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(14)${CClear} : Custom Event Log Size? : ${CGreen}$LOGSIZE" - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite} | ${CClear}" - - if [ $CHANGES -eq 0 ]; then - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( s)${CClear} : Save Config & Exit" - else - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( s)${CClear} : Save Config & Exit ${CWhite}${InvRed}<-- Save your changes! ${CClear}" - fi - - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( e)${CClear} : Exit & Discard Changes" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" - echo "" - read -p "Please select? (1-14, s=Save, e=Exit): " ConfigSelection - CHANGES=1 - # Execute chosen selections - case "$ConfigSelection" in - - 1) # ----------------------------------------------------------------------------------------- - while true - do - clear - echo -e "${InvGreen} ${InvDkGray}${CWhite} Refresh Interval ${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} Please indicate after how many seconds you would like RTRMON to refresh your stats?${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} (Default = 10 seconds)${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" - echo - echo -e "${CClear}Current Refresh Interval: ${CGreen}${Interval}${CClear} seconds" - echo - read -p "Please enter value in seconds [5-999] (e=Exit): " newInterval - if [ -z "$newInterval" ] || echo "$newInterval" | grep -qE "^(e|E)$" - then - if echo "$Interval" | grep -qE "^([1-9][0-9]{0,2})$" && \ - [ "$Interval" -ge 5 ] && [ "$Interval" -le 999 ] - then - timer="$Interval" - printf "\n${CClear}[Exiting]\n" - sleep 1 ; break - else - printf "\n${CRed}*ERROR*: Please enter a valid number between 5 and 999.${CClear}\n" - _PressAnyKeyToContinue_ - fi - elif echo "$newInterval" | grep -qE "^([1-9][0-9]{0,2})$" && \ - [ "$newInterval" -ge 5 ] && [ "$newInterval" -le 999 ] - then - Interval="$newInterval" - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new refresh interval ($Interval) has been selected." >> $LOGFILE - CHANGES=1 - timer="$Interval" - printf "\n${CClear}[OK]\n" - sleep 1 ; break - else - printf "\n${CRed}*ERROR*: Please enter a valid number between 5 and 999.${CClear}\n" - _PressAnyKeyToContinue_ - fi - done - ;; - - 2) # ----------------------------------------------------------------------------------------- - clear - echo -e "${InvGreen} ${InvDkGray}${CWhite} Maximum Internet Download Bandwidth ${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} Please indicate what your maximum internet download bandwidth/speed is in Mbps?${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} (Default = 50 Mbps)${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" - echo "" - echo -e "${CClear}Current: ${CGreen}$MaxSpeedInet${CClear} Mbps" - echo "" - read -p 'Please enter value in Mbps (ex: 1000): ' MaxSpeedInet1 - MaxSpeedInet2=$(echo $MaxSpeedInet1 | tr -d -c 0-9) - if [ -z "$MaxSpeedInet1" ]; then MaxSpeedInet=50; else MaxSpeedInet=$MaxSpeedInet2; fi - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new Internet Download Bandwidth soeed ($MaxSpeedInet Mbps) has been selected." >> $LOGFILE - ;; - - 3) # ----------------------------------------------------------------------------------------- - clear - echo -e "${InvGreen} ${InvDkGray}${CWhite} Maximum Internet Upload Bandwidth ${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} Please indicate what your maximum internet upload bandwidth/speed is in Mbps?${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} (Default = 50 Mbps)${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" - echo "" - echo -e "${CClear}Current: ${CGreen}$MaxSpeedInetUL${CClear} Mbps" - echo "" - read -p 'Please enter value in Mbps (ex: 1000): ' MaxSpeedInetUL1 - MaxSpeedInetUL2=$(echo $MaxSpeedInetUL1 | tr -d -c 0-9) - if [ -z "$MaxSpeedInetUL1" ]; then MaxSpeedInetUL=50; else MaxSpeedInetUL=$MaxSpeedInetUL2; fi - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new Internet Upload Bandwidth speed ($MaxSpeedInetUL Mbps) has been selected." >> $LOGFILE - ;; - - 4) # ----------------------------------------------------------------------------------------- - clear - echo -e "${InvGreen} ${InvDkGray}${CWhite} Maximum Local Area Network (LAN) Bandwidth ${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} Please indicate what your maximum LAN bandwidth/speed is in Mbps?${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} (Default = 1000 Mbps)${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" - echo "" - echo -e "${CClear}Current: ${CGreen}$MaxSpeedLAN${CClear} Mbps" - echo "" - read -p 'Please enter value in Mbps (ex: 1000): ' MaxSpeedLAN1 - MaxSpeedLAN2=$(echo $MaxSpeedLAN1 | tr -d -c 0-9) - if [ -z "$MaxSpeedLAN1" ]; then MaxSpeedLAN=1000; else MaxSpeedLAN=$MaxSpeedLAN2; fi - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new LAN Bandwidth speed ($MaxSpeedLAN Mbps) has been selected." >> $LOGFILE - ;; - - 5) # ----------------------------------------------------------------------------------------- - clear - echo -e "${InvGreen} ${InvDkGray}${CWhite} Maximum 2.4GHz Bandwidth Speed ${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} Please indicate what your maximum realistic 2.4GHz speed is in Mbps?${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} (Default = 450 Mbps)${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" - echo "" - echo -e "${CClear}Current: ${CGreen}$MaxSpeed24Ghz${CClear} Mbps" - echo "" - read -p 'Please enter value in Mbps (ex: 1000): ' MaxSpeed24Ghz1 - MaxSpeed24Ghz2=$(echo $MaxSpeed24Ghz1 | tr -d -c 0-9) - if [ -z "$MaxSpeed24Ghz1" ]; then MaxSpeed24Ghz=450; else MaxSpeed24Ghz=$MaxSpeed24Ghz2; fi - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new 2.4GHz Bandwidth speed ($MaxSpeed24Ghz Mbps) has been selected." >> $LOGFILE - ;; - - 6) # ----------------------------------------------------------------------------------------- - clear - echo -e "${InvGreen} ${InvDkGray}${CWhite} Maximum 5GHz Bandwidth Speed ${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} Please indicate what your maximum realistic 5GHz speed is in Mbps?${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} (Default = 780 Mbps)${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" - echo "" - echo -e "${CClear}Current: ${CGreen}$MaxSpeed5Ghz${CClear} Mbps" - echo "" - read -p 'Please enter value in Mbps (ex: 1000): ' MaxSpeed5Ghz1 - MaxSpeed5Ghz2=$(echo $MaxSpeed5Ghz1 | tr -d -c 0-9) - if [ -z "$MaxSpeed5Ghz1" ]; then MaxSpeed5Ghz=780; else MaxSpeed5Ghz=$MaxSpeed5Ghz2; fi - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new 5GHz Bandwidth speed ($MaxSpeed5Ghz Mbps) has been selected." >> $LOGFILE - ;; - - 7) # ----------------------------------------------------------------------------------------- - clear - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then - echo -e "${InvGreen} ${InvDkGray}${CWhite} Maximum 6GHz Bandwidth Speed ${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} Please indicate what your maximum realistic 6GHz speed is in Mbps?${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} (Default = 920 Mbps)${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" - echo "" - echo -e "${CClear}Current: ${CGreen}$MaxSpeed6Ghz${CClear} Mbps" - echo "" - read -p 'Please enter value in Mbps (ex: 1000): ' MaxSpeed6Ghz1 - MaxSpeed6Ghz2=$(echo $MaxSpeed6Ghz1 | tr -d -c 0-9) - if [ -z "$MaxSpeed6Ghz1" ]; then MaxSpeed6Ghz=920; else MaxSpeed6Ghz=$MaxSpeed6Ghz2; fi - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new 6GHz Bandwidth speed ($MaxSpeed6Ghz Mbps) has been selected." >> $LOGFILE - else - echo -e "${CRed}This item is currently only available for router models:" - echo -e "GT-AXE11000, GT-AXE16000, RT-BE96U, RT-BE92U and GT-BE98_Pro" - echo "" - sleep 3 - fi - ;; - - 8) # ----------------------------------------------------------------------------------------- - while true - do - clear - echo -e "${InvGreen} ${InvDkGray}${CWhite} Temperature Unit Preferences ${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} Please indicate what Temperature Units you would prefer to use?${CClear}" - echo -e "${InvGreen} ${CClear} (C)elcius, (F)ahrenheit or (K)elvin" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} (Default = C)${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" - echo "" - echo -e "${CClear}Current: ${CGreen}$TempUnits${CClear}" - echo "" - read -p 'Temp Units (C/F/K): ' TempUnits1 - case "$TempUnits1" in - [Cc]) TempUnits="C" ; break ;; - [Ff]) TempUnits="F" ; break ;; - [Kk]) TempUnits="K" ; break ;; - *) - printf "\n*ERROR*: Please enter a valid option.${CClear}\n" - sleep 2 - ;; - esac - done - if [ -z "$TempUnits1" ]; then TempUnits="C"; fi - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new Temperature Unit ($TempUnits) has been selected." >> $LOGFILE - ;; - - 9) # ----------------------------------------------------------------------------------------- - echo "" - if [ -f $OOKLAPATH ]; then - clear - echo -e "${InvGreen} ${InvDkGray}${CWhite} Remove Ookla Speedtest Binaries ${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} Would you like to disable and uninstall the Ookla Speedtest binaries from RTRMON?${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" - echo "" - echo -e "${CClear}Current: ${CGreen}Ookla Speedtest Installed${CClear}" - echo "" - echo -e "Remove Speedtest binaries from RTRMON?${CClear}" - if promptyn "[y/n]: " - then - echo "" - echo "" - echo -e "${CClear}Removing Ookla Speedtest binaries..." - rm "/jffs/addons/rtrmon.d/speedtest" - rm "/jffs/addons/rtrmon.d/speedtest.5" - rm "/jffs/addons/rtrmon.d/speedtest.md" - sleep 1 - if [ ! -f $OOKLAPATH ]; then - echo "" - echo -e "${CClear}Completed removing Ookla Speedtest binaries..." - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: Ookla Speedtest binaries have been successfully removed." >> $LOGFILE - Speedtst=0 - spdtestsvrID=0 - echo "" - read -rsp $'Press any key to continue...\n' -n1 key - else - echo "" - echo -e "${CRed}ERROR: Ookla Speedtest binaries were unable to be removed...${CClear}" - echo -e "Please manually resolve issue under /jffs/addons/rtrmon.d folder" - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - ERROR: Ookla Speedtest binaries were unable to be successfully removed." >> $LOGFILE - Speedtst=1 - echo "" - read -rsp $'Press any key to continue...\n' -n1 key - fi - else - echo "" - echo "" - echo -e "${CClear}Canceling removing Ookla Speedtest binaries..." - sleep 2 - fi - - else - clear - echo -e "${InvGreen} ${InvDkGray}${CWhite} Install Ookla Speedtest Binaries ${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} Would you like to install and enable the Ookla Speedtest binaries for use with${CClear}" - echo -e "${InvGreen} ${CClear} RTRMON? Please read the following before accepting agreement:${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} You may only use this Speedtest software and information generated from it for${CClear}" - echo -e "${InvGreen} ${CClear} personal, non-commercial use, through a command line interface on a personal${CClear}" - echo -e "${InvGreen} ${CClear} computer. Your use of this software is subject to the End User License${CClear}" - echo -e "${InvGreen} ${CClear} Agreement, Terms of Use and Privacy Policy at these URLs:${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} https://www.speedtest.net/about/eula${CClear}" - echo -e "${InvGreen} ${CClear} https://www.speedtest.net/about/terms${CClear}" - echo -e "${InvGreen} ${CClear} https://www.speedtest.net/about/privacy${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" - echo "" - echo -e "${CClear}Current: ${CGreen}Ookla Speedtest Not Installed${CClear}" - echo "" - echo -e "By typing 'y' below, you agree to these terms.${CClear}" - if promptyn "[y/n]: "; then - echo "" - echo "" - echo -e "Installing Ookla Speedtest binaries..." - echo "" - if [ "$(uname -m)" = "aarch64" ]; then - curl --silent --retry 3 "https://install.speedtest.net/app/cli/ookla-speedtest-1.2.0-linux-aarch64.tgz" -o "/jffs/addons/rtrmon.d/spdtst64.tgz" - tar -zxf /jffs/addons/rtrmon.d/spdtst64.tgz -C /jffs/addons/rtrmon.d 2>/dev/null - chmod 0755 "/jffs/addons/rtrmon.d/speedtest" - rm /jffs/addons/rtrmon.d/spdtst64.tgz - else - curl --silent --retry 3 "https://install.speedtest.net/app/cli/ookla-speedtest-1.2.0-linux-armel.tgz" -o "/jffs/addons/rtrmon.d/spdtstel.tgz" - tar -zxf /jffs/addons/rtrmon.d/spdtstel.tgz -C /jffs/addons/rtrmon.d 2>/dev/null - chmod 0755 "/jffs/addons/rtrmon.d/speedtest" - rm /jffs/addons/rtrmon.d/spdtstel.tgz - fi - if [ -f /jffs/addons/rtrmon.d/speedtest ]; then - echo -e "${CClear}Ookla Speedtest binaries installed successfully..." - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: Ookla Speedtest binaries were successfully installed." >> $LOGFILE - Speedtst=1 - echo "" - read -rsp $'Press any key to initialize Speedtest and accept license...\n' -n1 key - /jffs/addons/rtrmon.d/speedtest - cp /root/.config/ookla/speedtest-cli.json /jffs/addons/rtrmon.d/speedtest-cli.json 2>/dev/null - echo "" - read -rsp $'Press any key to continue...\n' -n1 key - else - echo -e "${CRed}ERROR: Ookla Speedtest binaries install failed...${CClear}" - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - ERROR: Ookla Speedtest binaries were unable to be successfully installed." >> $LOGFILE - Speedtst=0 - spdtestsvrID=0 - echo "" - read -rsp $'Press any key to continue...\n' -n1 key - fi - else - echo "" - echo "" - echo -e "${CClear}Canceling install of Ookla Speedtest binaries..." - Speedtst=0 - spdtestsvrID=0 - sleep 2 - fi - fi - ;; - - 10) # ----------------------------------------------------------------------------------------- - if [ "$Speedtst" == "0" ]; then return; fi - clear - echo -e "${InvGreen} ${InvDkGray}${CWhite} Custom Speedtest Server ID ${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} Please indicate if you would like to use a custom Speedtest Server ID? These IDs${CClear}" - echo -e "${InvGreen} ${CClear} can be found by running a Speedtest on your browser and noting the ID of the server${CClear}" - echo -e "${InvGreen} ${CClear} in its URL when hovering your mouse over it. Enter an ID number, or use 0 to choose${CClear}" - echo -e "${InvGreen} ${CClear} the closest server to you.${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} (Default = 0)${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" - echo "" - echo -e "${CClear}Current: ${CGreen}$spdtestsvrID${CClear}" - echo "" - read -p 'Speedtest Server ID: ' spdtestsvrID1 - spdtestsvrID2=$(echo $spdtestsvrID1 | tr -d -c 0-9) - if [ -z "$spdtestsvrID1" ]; then spdtestsvrID=0; else spdtestsvrID=$spdtestsvrID2; fi - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: Ookla Speedtest custom server ID ($spdtestsvrID) was configured." >> $LOGFILE - ;; - - 11) # ----------------------------------------------------------------------------------------- - clear - echo -e "${InvGreen} ${InvDkGray}${CWhite} Override WAN0 Interface ${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} Please indicate if you would like to override the default interface assigned to${CClear}" - echo -e "${InvGreen} ${CClear} your local WAN0? Typically, 'eth0' is assigned to WAN0, but based on how you've${CClear}" - echo -e "${InvGreen} ${CClear} rigged your router, it might be something else. By default, RTRMON will${CClear}" - echo -e "${InvGreen} ${CClear} automatically try to determine the correct interface, however this will give${CClear}" - echo -e "${InvGreen} ${CClear} you the option to override it should you be using something else.${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} (Default = 0)${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" - echo "" - echo -e "${CClear}Current: ${CGreen}$WANOverride${CClear}" - echo "" - echo -e "${CGreen}Valid interface choices:" - - ip -br link | LC_ALL=C awk '$2 == "UP" {print $1}' > $IFLIST # Extract all valid interfaces to a text file - - LINES=$(cat $IFLIST | wc -l) #Check to see how many lines are in this file - - echo -e "${CClear}0) Auto" - - i=0 # Populate all other numbered choices - while [ $i -ne $LINES ] - do - i=$(($i+1)) - InterfaceName=$(sed -n "${i}p" $IFLIST) - echo -e "$i) $InterfaceName" - done - - echo -e "${CClear}" - echo -e "(Default = 0 (Auto), or choose one of the above)${CClear}" - - while true - do - read -p 'Choose Interface #: ' ChooseInterface - - case ${ChooseInterface#[-+]} in # Make sure we're only picking an item from the list - *[!0-9]* | '') echo ""; echo -e "\n${CRed}ERROR: Please make a valid selection${CClear}"; echo "" ;; - * ) if [ $ChooseInterface -lt 0 ] || [ $ChooseInterface -gt $LINES ]; then echo ""; echo -e "\n${CRed}Please make a valid selection${CClear}"; echo ""; else break; fi ;; - esac - - done - - if [ -z "$ChooseInterface" ] # Assign the interface name to a variable and save it - then - WANOverride="Auto" - elif [ $ChooseInterface -eq 0 ] - then - WANOverride="Auto" - else - WANOverride=$(sed -n "${ChooseInterface}p" $IFLIST) - fi - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: WAN0 Override ($WANOverride) was configured." >> $LOGFILE - ;; - - 12) # ----------------------------------------------------------------------------------------- - clear - echo -e "${InvGreen} ${InvDkGray}${CWhite} Mark Router As iMesh Node/Repeater/Bridge ${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} Please indicate if you would like to mark that this router is being used as an${CClear}" - echo -e "${InvGreen} ${CClear} iMesh Node, Repeater or Bridge operating mode. In cases like this, the WAN0${CClear}" - echo -e "${InvGreen} ${CClear} interface will be non-functional, and will be omitted from being captured by${CClear}" - echo -e "${InvGreen} ${CClear} RTRMON's stats.${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} (Default = No)${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" - echo "" - if [ "$WAN0AltModes" == "0" ]; then WAN0AltModesdisp="No"; else WAN0AltModesdisp="Yes"; fi - echo -e "${CClear}Current: ${CGreen}$WAN0AltModesdisp${CClear}" - echo "" - echo -e "Is this router an iMesh Node/Repeater/Bridge?${CClear}" - if promptyn "[y/n]: "; then - WAN0AltModes=1 - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: This device's operating mode was marked as an iMesh Node/AP/Repeater/Bridge." >> $LOGFILE - else - WAN0AltModes=0 - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: This device's operating mode was marked as a Router." >> $LOGFILE - fi - ;; - - 13) # ----------------------------------------------------------------------------------------- - clear - echo -e "${InvGreen} ${InvDkGray}${CWhite} Mark VPN As Site-To-Site Only ${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} Please indicate if you would like to mark that this router is purely being used${CClear}" - echo -e "${InvGreen} ${CClear} in a VPN Site-To-Site only configuration. In cases like this, the public-facing${CClear}" - echo -e "${InvGreen} ${CClear} IP is a private IP, which could hinder certain network connection and bandwidth$CClear}" - echo -e "${InvGreen} ${CClear} tests, and potentially cause delays and/or a lack of data.${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} By default, it is assumed that this router's VPN configuration will be marked${CClear}" - echo -e "${InvGreen} ${CClear} as being in a normal VPN provider configuration.${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} (Default = No)${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" - echo "" - if [ "$VPNSite2Site" == "0" ]; then VPNSite2Sitedisp="No"; else VPNSite2Sitedisp="Yes"; fi - echo -e "${CClear}Current: ${CGreen}$VPNSite2Sitedisp${CClear}" - echo "" - echo -e "Is this router purely used in a VPN Site-to-Site Configuration?${CClear}" - if promptyn "[y/n]: "; then - VPNSite2Site=1 - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: This device's VPN operating mode was marked as being in a VPN Site-to-Site only configuration." >> $LOGFILE - else - VPNSite2Site=0 - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: This device's VPN operating mode was marked as being in a Normal VPN Provider configuration." >> $LOGFILE - fi - ;; - - 14) - clear - echo -e "${InvGreen} ${InvDkGray}${CWhite} Custom Event Log Size ${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} Please indicate below how large you would like your Event Log to grow. I'm a poet${CClear}" - echo -e "${InvGreen} ${CClear} and didn't even know it. By default, with 2000 rows, you will have many months of${CClear}" - echo -e "${InvGreen} ${CClear} Event Log data." - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} Use 0 to Disable, max number of rows is 9999. (Default = 2000)" - echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" - echo "" - echo -e "${CClear}Current: ${CGreen}$LOGSIZE${CClear}" - echo "" - read -p "Please enter Log Size (in rows)? (0-9999, e=Exit): " NEWLOGSIZE - if [ -z "$NEWLOGSIZE" ] || [ "$NEWLOGSIZE" = "e" ] - then - printf "\n[Exiting]\n"; sleep 2 - elif [ $NEWLOGSIZE -ge 0 ] && [ $NEWLOGSIZE -le 9999 ] - then - LOGSIZE="$NEWLOGSIZE" - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: New custom Event Log Size entered (in rows): $LOGSIZE" >> $LOGFILE - else - LOGSIZE=2000 - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: New custom Event Log Size entered (in rows): $LOGSIZE" >> $LOGFILE - fi - ;; - - [Ss]) # ----------------------------------------------------------------------------------------- - echo "" - { echo 'Interval='$Interval - echo 'MaxSpeedInet='$MaxSpeedInet - echo 'MaxSpeedInetUL='$MaxSpeedInetUL - echo 'MaxSpeedLAN='$MaxSpeedLAN - echo 'MaxSpeed24Ghz='$MaxSpeed24Ghz - echo 'MaxSpeed5Ghz='$MaxSpeed5Ghz - echo 'MaxSpeed6Ghz='$MaxSpeed6Ghz - echo 'TempUnits="'"$TempUnits"'"' - echo 'Speedtst='$Speedtst - echo 'spdtestsvrID='$spdtestsvrID - echo 'WANOverride="'"$WANOverride"'"' - echo 'WAN0AltModes='$WAN0AltModes - echo 'VPNSite2Site='$VPNSite2Site - echo 'LOGSIZE='$LOGSIZE - } > $CFGPATH - echo -e "\n${CClear}Applying config changes to RTRMON..." - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: New Config file was successfully written." >> $LOGFILE - sleep 3 - return - ;; - - [Ee]) # ----------------------------------------------------------------------------------------- - return - ;; - - esac - done - - else - #Create a new config file with default values to get it to a basic running state - { echo 'Interval=10' - echo 'MaxSpeedInet=1000' - echo 'MaxSpeedInetUL=50' - echo 'MaxSpeedLAN=1000' - echo 'MaxSpeed24Ghz=450' - echo 'MaxSpeed5Ghz=780' - echo 'MaxSpeed6Ghz=920' - echo 'TempUnits="C"' - echo 'Speedtst=0' - echo 'spdtestsvrID=0' - echo 'WANOverride="Auto"' - echo 'WAN0AltModes=0' - echo 'VPNSite2Site=0' - echo 'LOGSIZE=2000' - } > $CFGPATH - - #Re-run rtrmon -config to restart setup process - vconfig - - fi - -} - -# ------------------------------------------------------------------------------------------------------------------------- - -# vuninstall is a function that uninstalls and removes all traces of RTRMON from your router... -vuninstall () { - clear - echo -e "${InvGreen} ${InvDkGray}${CWhite} Uninstall Utility ${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} You are about to uninstall RTRMON! This action is irreversible." - echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" - echo "" - echo -e "Do you wish to proceed?${CClear}" - if promptyn "[y/n]: "; then - echo "" - echo -e "\nAre you sure? Please type 'Y' to validate you want to proceed.${CClear}" - if promptyn "[y/n]: "; then - clear - rm -r /jffs/addons/rtrmon.d - rm /jffs/scripts/rtrmon.sh - echo "" - echo -e "\nRTRMON has been uninstalled...${CClear}" - echo "" - exit 0 - else - echo "" - echo -e "\nExiting Uninstall Utility...${CClear}" - sleep 1 - return - fi - else - echo "" - echo -e "\nExiting Uninstall Utility...${CClear}" - sleep 1 - return - fi -} - - -# ------------------------------------------------------------------------------------------------------------------------- - -# vupdate is a function that provides a UI to check for script updates and allows you to install the latest version... -vupdate () { - updatecheck # Check for the latest version from source repository - clear - echo -e "${InvGreen} ${InvDkGray}${CWhite} Update Utility ${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} This utility allows you to check, download and install updates" - echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" - echo "" - echo -e "Current Version: ${CGreen}$Version${CClear}" - echo -e "Updated Version: ${CGreen}$DLVersion${CClear}" - echo "" - if [ "$Version" == "$DLVersion" ] - then - echo -e "You are on the latest version! Would you like to download anyways?${CClear}" - echo -e "This will overwrite your local copy with the current build.${CClear}" - if promptyn "[y/n]: "; then - echo "" - echo "" - echo -e "Downloading RTRMON ${CGreen}v$DLVersion${CClear}" - curl --silent --retry 3 "https://raw.githubusercontent.com/ViktorJp/RTRMON/master/rtrmon.sh" -o "/jffs/scripts/rtrmon.sh" && chmod 755 "/jffs/scripts/rtrmon.sh" - echo "" - echo -e "Download successful!${CClear}" - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: Successfully downloaded RTRMON v$DLVersion." >> $LOGFILE - echo "" - read -rsp $'Press any key to continue...\n' -n1 key - exec sh /jffs/scripts/rtrmon.sh -monitor - else - echo "" - echo "" - echo -e "Exiting Update Utility...${CClear}" - sleep 1 - return - fi - else - echo -e "Score! There is a new version out there! Would you like to update?${CClear}" - if promptyn "[y/n]: "; then - echo "" - echo "" - echo -e "Downloading RTRMON ${CYellow}v$DLVersion${CClear}" - curl --silent --retry 3 "https://raw.githubusercontent.com/ViktorJp/RTRMON/master/rtrmon.sh" -o "/jffs/scripts/rtrmon.sh" && chmod 755 "/jffs/scripts/rtrmon.sh" - echo "" - echo -e "Download successful!${CClear}" - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: Successfully downloaded RTRMON v$DLVersion." >> $LOGFILE - echo "" - read -rsp $'Press any key to continue...\n' -n1 key - exec sh /jffs/scripts/rtrmon.sh -monitor - else - echo "" - echo "" - echo -e "Exiting Update Utility...${CClear}" - sleep 1 - return - fi - fi -} - -# ------------------------------------------------------------------------------------------------------------------------- -##----------------------------------------## -## Modified by Martinski W. [2024-Nov-02] ## -##----------------------------------------## -# Function that sets up, configures and allows you to launch RTRMON on your router... -vsetup() -{ - _SetUpTimeoutCmdVars_ - - # Check for and add an alias for RTRMON # - if ! grep -F "sh /jffs/scripts/rtrmon.sh" /jffs/configs/profile.add >/dev/null 2>/dev/null; then - echo "alias rtrmon=\"sh /jffs/scripts/rtrmon.sh\" # RTRMON" >> /jffs/configs/profile.add - fi - - while true - do - clear - echo -e "${InvGreen} ${InvDkGray}${CWhite} RTRMON Main Setup and Configuration Menu ${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} Please choose from the various options below, which allow you to perform high level${CClear}" - echo -e "${InvGreen} ${CClear} actions in the management of the RTRMON script.${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(1)${CClear} : Setup and Configure RTRMON" - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(2)${CClear} : Force Re-install Entware Dependencies" - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(3)${CClear} : Check for latest updates" - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(4)${CClear} : View logs" - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(5)${CClear} : Uninstall" - if [ "$FromUI" == "0" ]; then - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite} | ${CClear}" - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(6)${CClear} : Launch RTRMON into Normal Monitoring Mode" - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(7)${CClear} : Launch RTRMON into Normal Monitoring Mode w/ SCREEN" - fi - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite} | ${CClear}" - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(e)${CClear} : Exit" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" - echo "" - if [ "$FromUI" == "0" ]; then - read -p "Please select? (1-7, e=Exit): " InstallSelection - else - read -p "Please select? (1-5, e=Exit): " InstallSelection - fi - - # Execute chosen selections - case "$InstallSelection" in - - 1) # Check for existence of entware, and if so proceed and install the timeout package, then run RTRMON -config - clear - if [ -f "/opt/bin/column" ] && [ -f "/opt/bin/timeout" ] && [ -f "/opt/sbin/screen" ] && [ -f "/opt/bin/nmap" ] && [ -f "/opt/bin/jq" ] && [ -f "/opt/bin/iftop" ] - then - vconfig - else - echo -e "${InvGreen} ${InvDkGray}${CWhite} Install Dependencies ${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} Missing dependencies required by RTRMON will be installed during this process." - echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" - echo "" - echo -e "RTRMON will require the installation of CoreUtils-Timeout, Screen and Nmap utilities." - echo -e "These utilities require you to have Entware already installed using the AMTM tool. If" - echo -e "Entware is present, the Timeout, Screen and Nmap utilities will be downloaded and" - echo -e "installed during this setup process, and utilized by RTRMON." - echo "" - echo -e "${CGreen}CoreUtils-Timeout${CClear} is a utility that provides more stability for certain routers (like" - echo -e "the RT-AC86U) which has a tendency to randomly hang scripts running on this router model." - echo "" - echo -e "${CGreen}Screen${CClear} is a utility that allows you to run SSH scripts in a standalone" - echo -e "environment directly on the router itself, instead of running your commands or a script" - echo -e "from a network-attached SSH client. This can provide greater stability due to it running" - echo -e "from the router itself." - echo "" - echo -e "${CGreen}Nmap${CClear} is a network discovery and security auditing tool that is used to scan your LAN," - echo -e "WAN and VPN connections for open ports." - echo "" - echo -e "${CGreen}JQuery${CClear} is a utility for querying data across the internet for the purposes of" - echo -e "interacting with the various VPN providers to get a list of APIs available VPN hosts in" - echo -e "the selected country." - echo "" - echo -e "${CGreen}iftop${CClear} is a utility for querying connection and bandwidth data." - echo "" - echo -e "${CGreen}Column${CClear} is a utility used to neatly arrange data on screen." - echo "" - echo -e "Your router model is: ${CGreen}${RouterModel}${CClear}" - echo "" - echo -e "Ready to install?" - if promptyn "[y/n]: " - then - if [ -d "/opt" ]; then # Does entware exist? If yes proceed, if no error out. - echo "" - echo -e "\n${CClear}Updating Entware Packages..." - echo "" - opkg update - echo "" - echo -e "Installing Entware ${CGreen}CoreUtils-Timeout${CClear} Package..." - echo "" - opkg install coreutils-timeout - echo "" - echo -e "Installing Entware ${CGreen}Screen Package${CClear}..." - echo "" - opkg install screen - echo "" - echo -e "Installing Entware ${CGreen}Nmap${CClear} Package..." - echo "" - opkg install nmap - echo "" - echo -e "Installing Entware ${CGreen}JQuery${CClear} Package..." - echo "" - opkg install jq - echo "" - echo -e "Installing Entware ${CGreen}iftop${CClear} Package..." - echo "" - opkg install iftop - echo "" - echo -e "Installing Entware ${CGreen}Column${CClear} Package..." - echo "" - opkg install column - echo "" - echo -e "Install completed..." - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: Entware dependencies were successfully installed." >> $LOGFILE - echo "" - read -rsp $'Press any key to continue...\n' -n1 key - echo "" - echo -e "Executing RTRMON Configuration Utility..." - sleep 2 - vconfig - else - clear - echo -e "${CRed}ERROR: Entware was not found on this router...${CClear}" - echo -e "Please install Entware using the AMTM utility before proceeding..." - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - ERROR: Entware was not found on this router. Please install using AMTM utility." >> $LOGFILE - echo "" - sleep 3 - fi - else - echo "" - echo -e "\nExecuting RTRMON Configuration Utility..." - sleep 2 - vconfig - fi - fi - ;; - - - 2) # Force re-install the CoreUtils timeout/screen package - clear - echo -e "${InvGreen} ${InvDkGray}${CWhite} Re-install Dependencies ${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} Missing dependencies required by RTRMON will be re-installed during this process." - echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" - echo "" - echo -e "VPNMON-R3 has some dependencies in order to function correctly, namely, CoreUtils-Timeout" - echo -e "RTRMON will require the installation of CoreUtils-Timeout, Screen, Nmap, JQ and iftop" - echo -e "utilities. These utilities require you to have Entware already installed using AMTM. If" - echo -e "Entware is present, the Timeout, Screen, Nmap, JQ and iftop utilities will be downloaded" - echo -e "and re-installed during this setup process, and utilized by RTRMON." - echo "" - echo -e "${CGreen}CoreUtils-Timeout${CClear} is a utility that provides more stability for certain routers (like" - echo -e "the RT-AC86U) which has a tendency to randomly hang scripts running on this router model." - echo "" - echo -e "${CGreen}Screen${CClear} is a utility that allows you to run SSH scripts in a standalone" - echo -e "environment directly on the router itself, instead of running your commands or a script" - echo -e "from a network-attached SSH client. This can provide greater stability due to it running" - echo -e "from the router itself." - echo "" - echo -e "${CGreen}Nmap${CClear} is a network discovery and security auditing tool that is used to scan your LAN," - echo -e "WAN and VPN connections for open ports." - echo "" - echo -e "${CGreen}JQuery${CClear} is a utility for querying data across the internet for the purposes of" - echo -e "interacting with the various VPN providers to get a list of APIs available VPN hosts in" - echo -e "the selected country." - echo "" - echo -e "${CGreen}iftop${CClear} is a utility for querying connection and bandwidth data." - echo "" - echo -e "${CGreen}Column${CClear} is a utility used to neatly arrange data on screen." - echo "" - echo -e "Your router model is: ${CGreen}${RouterModel}${CClear}" - echo "" - echo -e "Force Re-install?" - if promptyn "[y/n]: " - then - if [ -d "/opt" ]; then # Does entware exist? If yes proceed, if no error out. - echo "" - echo -e "\n${CClear}Updating Entware Packages..." - echo "" - opkg update - echo "" - echo -e "Force Re-installing Entware ${CGreen}CoreUtils-Timeout${CClear} Package..." - echo "" - opkg install --force-reinstall coreutils-timeout - echo "" - echo -e "Force Re-installing Entware ${CGreen}Screen${CClear} Package..." - echo "" - opkg install --force-reinstall screen - echo "" - echo -e "Force Re-installing Entware ${CGreen}Nmap${CClear} Package..." - echo "" - opkg install --force-reinstall nmap - echo "" - echo -e "Force Re-installing Entware ${CGreen}JQuery${CClear} Package..." - echo "" - opkg install --force-reinstall jq - echo "" - echo -e "Force Re-installing Entware ${CGreen}iftop${CClear} Package..." - echo "" - opkg install --force-reinstall iftop - echo "" - echo -e "Force Re-installing Entware ${CGreen}Column${CClear} Package..." - echo "" - opkg install --force-reinstall column - echo "" - echo -e "Re-install completed..." - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: Entware dependencies were successfully re-installed." >> $LOGFILE - echo "" - read -rsp $'Press any key to continue...\n' -n1 key - else - clear - echo -e "${CRed}ERROR: Entware was not found on this router...${CClear}" - echo -e "Please install Entware using the AMTM utility before proceeding..." - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - ERROR: Entware was not found on this router. Please install using AMTM utility." >> $LOGFILE - echo "" - sleep 3 - fi - fi - ;; - - 3) - echo "" - vupdate - ;; - - 6) - echo "" - echo -e "\n${CGreen}Launching RTRMON into Monitor Mode...${CClear}" - sleep 2 - exec sh $APPPATH -monitor - ;; - - 7) - echo "" - echo -e "\n${CGreen}Launching RTRMON into Monitor Mode with Screen Utility...${CClear}" - sleep 2 - exec sh $APPPATH -screen - ;; - - 4) - echo "" - vlogs - ;; - - 5) - echo "" - vuninstall - ;; - - [Ee]) - echo -e "${CClear}" - timer="$Interval" - break - ;; - - *) - echo "" - echo -e "${CRed}Invalid choice - Please enter a valid option...${CClear}" - echo "" - sleep 2 - ;; - - esac - done -} - -# ------------------------------------------------------------------------------------------------------------------------- - -# get_wan_setting was "borrowed" graciously from @dave14305 from his FlexQoS script to determine the active WAN connection. -# Thanks much for your troubleshooting help as we tackled how to best derive the active WAN interface, Dave! -get_wan_setting() { - local varname varval - varname="${1}" - prefixes="wan0_ wan1_" - - if [ "$($timeoutcmd$timeoutsec nvram get wans_mode)" = "lb" ] ; then - for prefix in $prefixes; do - state="$($timeoutcmd$timeoutsec nvram get "${prefix}"state_t)" - sbstate="$($timeoutcmd$timeoutsec nvram get "${prefix}"sbstate_t)" - auxstate="$($timeoutcmd$timeoutsec nvram get "${prefix}"auxstate_t)" - - # is_wan_connect() - [ "${state}" = "2" ] || continue - [ "${sbstate}" = "0" ] || continue - [ "${auxstate}" = "0" ] || [ "${auxstate}" = "2" ] || continue - - # get_wan_ifname() - proto="$($timeoutcmd$timeoutsec nvram get "${prefix}"proto)" - if [ "${proto}" = "pppoe" ] || [ "${proto}" = "pptp" ] || [ "${proto}" = "l2tp" ] ; then - varval="$($timeoutcmd$timeoutsec nvram get "${prefix}"pppoe_"${varname}")" - else - varval="$($timeoutcmd$timeoutsec nvram get "${prefix}""${varname}")" - fi - done - else - for prefix in $prefixes; do - primary="$($timeoutcmd$timeoutsec nvram get "${prefix}"primary)" - [ "${primary}" = "1" ] && break - done - - proto="$($timeoutcmd$timeoutsec nvram get "${prefix}"proto)" - if [ "${proto}" = "pppoe" ] || [ "${proto}" = "pptp" ] || [ "${proto}" = "l2tp" ] ; then - varval="$($timeoutcmd$timeoutsec nvram get "${prefix}"pppoe_"${varname}")" - else - varval="$($timeoutcmd$timeoutsec nvram get "${prefix}""${varname}")" - fi - fi - printf "%s" "${varval}" -} # get_wan_setting - -# ------------------------------------------------------------------------------------------------------------------------- - -# gettopstats gathers the majority of cpu and memory related stats directly from the TOP utility -##----------------------------------------## -## Modified by Martinski W. [2024-Nov-02] ## -##----------------------------------------## -gettopstats () -{ - local numFields - - TotalMem="$(top -bn1 | head -n3 | grep -E '^Mem:|^CPU:|^Load' | awk 'NR==1 {print $2, $4, $6, $8, $10} NR==2 {print $2, $4, $6, $8, $14} NR==3 {print $3, $4, $5}' 2>/dev/null)" - - numFields="$(echo $TotalMem | awk -F ' ' '{print NF}')" - [ "$numFields" -lt 13 ] && return 1 - - #totalmemory based on the power of 2 to determine nearest estimated installed RAM - memtotal="$(awk '/^MemTotal:/ {print $2}' /proc/meminfo)" - totalreportedphysmem=$(awk 'BEGIN { printf "%.0f", ('"$memtotal"' / 1000) }') - next_power_of_2=$(awk -v num="$totalreportedphysmem" ' - BEGIN { - if (num == 0) { - print 1; - exit; - } - num--; - num = or(num, rshift(num, 1)); - num = or(num, rshift(num, 2)); - num = or(num, rshift(num, 4)); - num = or(num, rshift(num, 8)); - num = or(num, rshift(num, 16)); - # num = or(num, rshift(num, 32)); - num++; - print num; - } - ') - totalmemory="$next_power_of_2" - - memfree="$(awk '/^MemFree:/ {print $2}' /proc/meminfo)" - membuff="$(awk '/^Buffers:/ {print $2}' /proc/meminfo)" - memcach="$(awk '/^Cached:/ {print $2}' /proc/meminfo)" - memfree="$(awk 'BEGIN { printf "%.0f", ('"$memfree"' + '"$membuff"' + '"$memcach"') }')" - memshrd="$(awk '/^Shmem:/ {print $2}' /proc/meminfo)" - memused="$(awk 'BEGIN { printf "%.0f", ('"$totalmemory"' * 1000 - '"$memfree"') }')" - - cpuusr="$(echo $TotalMem | awk '{print $6}' | sed 's/%$//' | cut -d . -f 1)" - cpusys="$(echo $TotalMem | awk '{print $7}' | sed 's/%$//' | cut -d . -f 1)" - cpunice="$(echo $TotalMem | awk '{print $8}' | sed 's/%$//' | cut -d . -f 1)" - cpuidle="$(echo $TotalMem | awk '{print $9}' | sed 's/%$//' | cut -d . -f 1)" - cpuirq="$(echo $TotalMem | awk '{print $10}' | sed 's/%$//' | cut -d . -f 1)" - displaycpuusr="$(echo $TotalMem | awk '{print $6}' | sed 's/%$//')" - displaycpusys="$(echo $TotalMem | awk '{print $7}' | sed 's/%$//')" - displaycpunice="$(echo $TotalMem | awk '{print $8}' | sed 's/%$//')" - displaycpuidle="$(echo $TotalMem | awk '{print $9}' | sed 's/%$//')" - displaycpuirq="$(echo $TotalMem | awk '{print $10}' | sed 's/%$//')" - cpuload1m="$(echo $TotalMem | awk '{print $11}')" - cpuload5m="$(echo $TotalMem | awk '{print $12}')" - cpuload15m="$(echo $TotalMem | awk '{print $13}')" - - memused1="$((memused1 + memused))" - memfree1="$((memfree1 + memfree))" - memshrd1="$((memshrd1 + memshrd))" - membuff1="$((membuff1 + membuff))" - memcach1="$((memcach1 + memcach))" - cpuusr1="$((cpuusr1 + cpuusr))" - cpusys1="$((cpusys1 + cpusys))" - cpunice1="$((cpunice1 + cpunice))" - cpuidle1="$((cpuidle1 + cpuidle))" - cpuirq1="$((cpuirq1 + cpuirq))" - - displaycpuusr1="$(awk -v v1=$displaycpuusr1 -v v2=$displaycpuusr 'BEGIN{printf "%0.2f\n", v1+v2}')" - displaycpusys1="$(awk -v v1=$displaycpusys1 -v v2=$displaycpusys 'BEGIN{printf "%0.2f\n", v1+v2}')" - displaycpunice1="$(awk -v v1=$displaycpunice1 -v v2=$displaycpunice 'BEGIN{printf "%0.2f\n", v1+v2}')" - displaycpuidle1="$(awk -v v1=$displaycpuidle1 -v v2=$displaycpuidle 'BEGIN{printf "%0.2f\n", v1+v2}')" - displaycpuirq1="$(awk -v v1=$displaycpuirq1 -v v2=$displaycpuirq 'BEGIN{printf "%0.2f\n", v1+v2}')" - - return 0 -} - -# ------------------------------------------------------------------------------------------------------------------------- - -# oldstats holds the old (current) stats that are being used to display stats on-screen -oldstats() -{ - oldcpuusr1=$cpuusr1 - oldcpusys1=$cpusys1 - oldcpunice1=$cpunice1 - oldcpuidle1=$cpuidle1 - oldcpuirq1=$cpuirq1 - olddisplaycpuusr1=$displaycpuusr1 - olddisplaycpusys1=$displaycpusys1 - olddisplaycpunice1=$displaycpunice1 - olddisplaycpuidle1=$displaycpuidle1 - olddisplaycpuirq1=$displaycpuirq1 - oldF_cputemp=$F_cputemp - oldmemused2=$memused2 - oldmemfree2=$memfree2 - oldmemshrd2=$memshrd2 - oldmembuff2=$membuff2 - oldmemcach2=$memcach2 - oldtotalmemory=$totalmemory - oldnvramfree=$nvramfree - oldnvramused=$nvramused - oldtotalnvram=$totalnvram - oldjffstotal=$jffstotal - oldjffsused=$jffsused - oldswaptotal=$swaptotal - oldswapused=$swapused - if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then - oldwan0ip=$wan0ip - oldwan1ip=$wan1ip - fi - olddns1ip=$dns1ip - olddns2ip=$dns2ip - oldwanip6=$wanip6 - oldlanip6=$lanip6 - if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then - oldwanrxmbrate=$wanrxmbrate - oldwantxmbrate=$wantxmbrate - fi - oldw24rxmbrate=$w24rxmbrate - oldw24txmbrate=$w24txmbrate - oldw5rxmbrate=$w5rxmbrate - oldw5txmbrate=$w5txmbrate - oldw24temp=$w24temp - oldw5temp=$w5temp - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then - oldw52rxmbrate=$w52rxmbrate - oldw52txmbrate=$w52txmbrate - oldw52temp=$w52temp - fi - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then - oldw6rxmbrate=$w6rxmbrate - oldw6txmbrate=$w6txmbrate - oldw6temp=$w6temp - fi - if [ "$FourBandCustom56624" == "True" ]; then - oldw62rxmbrate=$w62rxmbrate - oldw62txmbrate=$w62txmbrate - oldw62temp=$w62temp - fi - - oldlanip=$lanip - oldlanrxmbrate=$lanrxmbrate - oldlantxmbrate=$lantxmbrate - - oldvpnrxmbrate=$vpnrxmbrate - oldvpntxmbrate=$vpntxmbrate - oldvpn2rxmbrate=$vpn2rxmbrate - oldvpn2txmbrate=$vpn2txmbrate - oldvpn3rxmbrate=$vpn3rxmbrate - oldvpn3txmbrate=$vpn3txmbrate - oldvpn4rxmbrate=$vpn4rxmbrate - oldvpn4txmbrate=$vpn4txmbrate - oldvpn5rxmbrate=$vpn5rxmbrate - oldvpn5txmbrate=$vpn5txmbrate - oldvpn1ip=$vpn1ip - oldvpn1city=$vpn1city - oldvpn2ip=$vpn2ip - oldvpn2city=$vpn2city - oldvpn3ip=$vpn3ip - oldvpn3city=$vpn3city - oldvpn4ip=$vpn4ip - oldvpn4city=$vpn4city - oldvpn5ip=$vpn5ip - oldvpn5city=$vpn5city - - oldwg1rxmbrate=$wg1rxmbrate - oldwg1txmbrate=$wg1txmbrate - oldwg2rxmbrate=$wg2rxmbrate - oldwg2txmbrate=$wg2txmbrate - oldwg3rxmbrate=$wg3rxmbrate - oldwg3txmbrate=$wg3txmbrate - oldwg4rxmbrate=$wg4rxmbrate - oldwg4txmbrate=$wg4txmbrate - oldwg5rxmbrate=$wg5rxmbrate - oldwg5txmbrate=$wg5txmbrate - oldwg1ip=$wg1ip - oldwg1city=$wg1city - oldwg2ip=$wg2ip - oldwg2city=$wg2city - oldwg3ip=$wg3ip - oldwg3city=$wg3city - oldwg4ip=$wg4ip - oldwg4city=$wg4city - oldwg5ip=$wg5ip - oldwg5city=$wg5city - - if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then - oldwanrxmbratedisplay=$wanrxmbratedisplay - oldwantxmbratedisplay=$wantxmbratedisplay - fi - oldw24rxmbratedisplay=$w24rxmbratedisplay - oldw24txmbratedisplay=$w24txmbratedisplay - oldw5rxmbratedisplay=$w5rxmbratedisplay - oldw5txmbratedisplay=$w5txmbratedisplay - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then - oldw52rxmbratedisplay=$w52rxmbratedisplay - oldw52txmbratedisplay=$w52txmbratedisplay - fi - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then - oldw6rxmbratedisplay=$w6rxmbratedisplay - oldw6txmbratedisplay=$w6txmbratedisplay - fi - if [ "$FourBandCustom56624" == "True" ]; then - oldw62rxmbratedisplay=$w62rxmbratedisplay - oldw62txmbratedisplay=$w62txmbratedisplay - fi - oldlanrxmbratedisplay=$lanrxmbratedisplay - oldlantxmbratedisplay=$lantxmbratedisplay - - oldvpnrxmbratedisplay=$vpnrxmbratedisplay - oldvpntxmbratedisplay=$vpntxmbratedisplay - oldvpn2rxmbratedisplay=$vpn2rxmbratedisplay - oldvpn2txmbratedisplay=$vpn2txmbratedisplay - oldvpn3rxmbratedisplay=$vpn3rxmbratedisplay - oldvpn3txmbratedisplay=$vpn3txmbratedisplay - oldvpn4rxmbratedisplay=$vpn4rxmbratedisplay - oldvpn4txmbratedisplay=$vpn4txmbratedisplay - oldvpn5rxmbratedisplay=$vpn5rxmbratedisplay - oldvpn5txmbratedisplay=$vpn5txmbratedisplay - - oldwg1rxmbratedisplay=$wg1rxmbratedisplay - oldwg1txmbratedisplay=$wg1txmbratedisplay - oldwg2rxmbratedisplay=$wg2rxmbratedisplay - oldwg2txmbratedisplay=$wg2txmbratedisplay - oldwg3rxmbratedisplay=$wg3rxmbratedisplay - oldwg3txmbratedisplay=$wg3txmbratedisplay - oldwg4rxmbratedisplay=$wg4rxmbratedisplay - oldwg4txmbratedisplay=$wg4txmbratedisplay - oldwg5rxmbratedisplay=$wg5rxmbratedisplay - oldwg5txmbratedisplay=$wg5txmbratedisplay -} - -# ------------------------------------------------------------------------------------------------------------------------- -##----------------------------------------## -## Modified by Martinski W. [2024-Nov-04] ## -##----------------------------------------## -# Calculates and captures, well, all the current stats from their sources ;) -calculatestats() -{ - - RM_END_TIME="$(date +%s)" - RM_ELAPSED_TIME=$((RM_END_TIME - RM_START_TIME)) - [ "$RM_ELAPSED_TIME" -eq 0 ] && return 1 - - # CPU - Usage - if [ -n "$cpuusr1" ]; then cpuusr1=$((cpuusr1 / Interval)); else cpuusr1=0; fi - if [ -n "$cpusys1" ]; then cpusys1=$((cpusys1 / Interval)); else cpusys1=0; fi - if [ -n "$cpunice1" ]; then cpunice1=$((cpunice1 / Interval)); else cpunice1=0; fi - if [ -n "$cpuidle1" ]; then cpuidle1=$((cpuidle1 / Interval)); else cpuidle1=0; fi - if [ -n "$cpuirq1" ]; then cpuirq1=$((cpuirq1 / Interval)); else cpuirq1=0; fi - if [ -n "$displaycpuusr1" ]; then displaycpuusr1=$(awk -v rb=$displaycpuusr1 -v intv=$Interval 'BEGIN{printf "%0.2f\n", rb/intv}'); else displaycpuusr1=0; fi - if [ -n "$displaycpusys1" ]; then displaycpusys1=$(awk -v rb=$displaycpusys1 -v intv=$Interval 'BEGIN{printf "%0.2f\n", rb/intv}'); else displaycpusys1=0; fi - if [ -n "$displaycpunice1" ]; then displaycpunice1=$(awk -v rb=$displaycpunice1 -v intv=$Interval 'BEGIN{printf "%0.2f\n", rb/intv}'); else displaycpunice1=0; fi - if [ -n "$displaycpuidle1" ]; then displaycpuidle1=$(awk -v rb=$displaycpuidle1 -v intv=$Interval 'BEGIN{printf "%0.2f\n", rb/intv}'); else displaycpuidle1=0; fi - if [ -n "$displaycpuirq1" ]; then displaycpuirq1=$(awk -v rb=$displaycpuirq1 -v intv=$Interval 'BEGIN{printf "%0.2f\n", rb/intv}'); else displaycpuirq1=0; fi - - # CPU - Temp - borrowed from @Maverickcdn - thank you! - if [ -f /sys/class/thermal/thermal_zone0/temp ]; then - F_cputemp=$($timeoutcmd$timeoutsec cat /sys/class/thermal/thermal_zone0/temp | cut -c -2) - elif [ -f /proc/dmu/temperature ]; then # Thanks to PeterR for the bug report on AC68U's - hopefully this will fix that - F_cputemp=$($timeoutcmd$timeoutsec cat /proc/dmu/temperature | cut -c19-20) - fi - - # Memory - Usage - if [ -n "$memused1" ]; then memused1=$((memused1 / Interval)); else memused1=0; fi - if [ -n "$memfree1" ]; then memfree1=$((memfree1 / Interval)); else memfree1=0; fi - if [ -n "$memshrd1" ]; then memshrd1=$((memshrd1 / Interval)); else memshrd1=0; fi - if [ -n "$membuff1" ]; then membuff1=$((membuff1 / Interval)); else membuff1=0; fi - if [ -n "$memcach1" ]; then memcach1=$((memcach1 / Interval)); else memcach1=0; fi - - totalphysmem="$totalmemory" - - memused2=$(awk 'BEGIN { printf "%.0f", ('"$memused1"' / 1000) }') - memfree2=$(awk 'BEGIN { printf "%.0f", ('"$memfree1"' / 1000) }') - memshrd2=$(awk 'BEGIN { printf "%.0f", ('"$memshrd1"' / 1000) }') - membuff2=$(awk 'BEGIN { printf "%.0f", ('"$membuff1"' / 1000) }') - memcach2=$(awk 'BEGIN { printf "%.0f", ('"$memcach1"' / 1000) }') - - # Memory - NVRAM -- Many thanks to @RMerlin, @SomewhereOverTheRainbow and @Ranger802004 for your help finding NVRAM stats - eval "$($timeoutcmd$timeoutsec nvram show >/tmp/output.txt 2> /tmp/size.txt)" - chmod 755 /tmp/size.txt - nvramtotals=$(cat /tmp/size.txt | grep size: | awk '{print $2, $4}' 2>/dev/null) - nvramused="$(echo $nvramtotals | awk '{print $1}')" - nvramfree="$(echo $nvramtotals | awk '{print $2}' | sed 's/[)(]//g')" - if [ -z $nvramused ] || [ -z $nvramfree ]; then - nvramused=10000 # incase the values coming back from this file are blank, use temporary fillers - totalnvram=20000 - else - totalnvram="$((nvramused + nvramfree))" - fi - - # Disk - JFFS - disk_use=$($timeoutcmd$timeoutsec df -P | grep -E '/jffs' | awk '{print $2, $3}') - jffstotal="$(echo $disk_use | awk '{print $1}')" - jffsused="$(echo $disk_use | awk '{print $2}')" - jffstotal=$(awk 'BEGIN { printf "%.0f", ('"$jffstotal"' / 1000) }') - jffsused=$(awk 'BEGIN { printf "%.0f", ('"$jffsused"' / 1000) }') - - # Disk - Swap file - swap_use=$($timeoutcmd$timeoutsec /usr/bin/free | awk 'NR==4 {print $2, $3}' 2>/dev/null) - swaptotal="$(echo $swap_use | awk '{print $1}')" - swapused="$(echo $swap_use | awk '{print $2}')" - swaptotal=$(awk 'BEGIN { printf "%.0f", ('"$swaptotal"' / 1000) }') - swapused=$(awk 'BEGIN { printf "%.0f", ('"$swapused"' / 1000) }') - if [ $swaptotal == "0" ]; then swaptotal=100; fi - - # Disk - SD devices - df | grep /dev/sd > /jffs/addons/rtrmon.d/sdresult.txt 2>/dev/null - - # Network - WAN/LAN/DNS IP Addresses - if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ] - then - wan0ip=$($timeoutcmd$timeoutsec nvram get wan0_ipaddr) - wan1ip=$($timeoutcmd$timeoutsec nvram get wan1_ipaddr) - fi - lanip=$($timeoutcmd$timeoutsec nvram get lan_ipaddr) - dns1ip="$($timeoutcmd$timeoutsec nvram get wan0_dns | awk '{print $1}')" - dns2ip="$($timeoutcmd$timeoutsec nvram get wan0_dns | awk '{print $2}')" - dns3ip="$($timeoutcmd$timeoutsec nvram get wan1_dns | awk '{print $1}')" - dns4ip="$($timeoutcmd$timeoutsec nvram get wan1_dns | awk '{print $2}')" - - if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ] - then - if [ -z $wan0ip ]; then dns1ip="0.0.0.0"; fi - if [ -z $wan1ip ]; then dns1ip="0.0.0.0"; fi - fi - if [ -z $lanip ]; then dns1ip="0.0.0.0"; fi - if [ -z $dns1ip ]; then dns1ip="0.0.0.0"; fi - if [ -z $dns2ip ]; then dns2ip="0.0.0.0"; fi - if [ $dns1ip == "0.0.0.0" ] && [ ! -z $dns3ip ]; then dns1ip=$dns3ip; fi - if [ $dns2ip == "0.0.0.0" ] && [ ! -z $dns4ip ]; then dns2ip=$dns4ip; fi - if [ "$vpn1on" == "False" ]; then vpn1ip="0.0.0.0"; fi - if [ "$vpn2on" == "False" ]; then vpn2ip="0.0.0.0"; fi - if [ "$vpn3on" == "False" ]; then vpn3ip="0.0.0.0"; fi - if [ "$vpn4on" == "False" ]; then vpn4ip="0.0.0.0"; fi - if [ "$vpn5on" == "False" ]; then vpn5ip="0.0.0.0"; fi - if [ "$wg1on" == "False" ]; then wg1ip="0.0.0.0"; fi - if [ "$wg2on" == "False" ]; then wg2ip="0.0.0.0"; fi - if [ "$wg3on" == "False" ]; then wg3ip="0.0.0.0"; fi - if [ "$wg4on" == "False" ]; then wg4ip="0.0.0.0"; fi - if [ "$wg5on" == "False" ]; then wg5ip="0.0.0.0"; fi - - # Many thanks to @SomewhereOverTheRainbow for his help and suggestions on getting IP6 info! - if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then - wanip6="$(ip -o -6 addr list "$WANIFNAME" scope global | awk 'NR==1{ split($4, ip_addr, "/"); print ip_addr[1] }')" - fi - lanip6="$(ip -o -6 addr list br0 scope global | awk 'NR==1{ split($4, ip_addr, "/"); print ip_addr[1] }')" - - # Network - Wifi - Temp - # Standard Dual-Band config - w24tempraw=$($timeoutcmd$timeoutsec wl -i $ifname24 phy_tempsense | awk '{print $1}' ) >/dev/null 2>&1 - w5tempraw=$($timeoutcmd$timeoutsec wl -i $ifname5 phy_tempsense | awk '{print $1}' ) >/dev/null 2>&1 - if [ -z $w24tempraw ] || [ $w24tempraw -eq 0 ]; then w24tempraw=1; fi #in case it does not return a valid number - if [ -z $w5tempraw ] || [ $w5tempraw -eq 0 ]; then w5tempraw=1; fi - w24temp=$(awk -v v1=$w24tempraw 'BEGIN{printf "\n" (v1/2)+20}' | cut -d . -f 1) - w5temp=$(awk -v v1=$w5tempraw 'BEGIN{printf "\n" (v1/2)+20}' | cut -d . -f 1) - - # Tri or Quad Band 5GHz - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then - w52tempraw=$($timeoutcmd$timeoutsec wl -i $ifname52 phy_tempsense | awk '{print $1}' ) >/dev/null 2>&1 - if [ -z $w52tempraw ] || [ $w52tempraw -eq 0 ]; then w52tempraw=1; fi - w52temp=$(awk -v v1=$w52tempraw 'BEGIN{printf "\n" (v1/2)+20}' | cut -d . -f 1) - fi - # Tri or Quad-Band 6GHz - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then - w6tempraw=$($timeoutcmd$timeoutsec wl -i $ifname6 phy_tempsense | awk '{print $1}' ) >/dev/null 2>&1 - if [ -z $w6tempraw ] || [ $w6tempraw -eq 0 ]; then w6tempraw=1; fi - w6temp=$(awk -v v1=$w6tempraw 'BEGIN{printf "\n" (v1/2)+20}' | cut -d . -f 1) - fi - if [ "$FourBandCustom56624" == "True" ]; then - w62tempraw=$($timeoutcmd$timeoutsec wl -i $ifname62 phy_tempsense | awk '{print $1}' ) >/dev/null 2>&1 - if [ -z $w62tempraw ] || [ $w62tempraw -eq 0 ]; then w62tempraw=1; fi - w62temp=$(awk -v v1=$w62tempraw 'BEGIN{printf "\n" (v1/2)+20}' | cut -d . -f 1) - fi - - # Network - Wifi - Up/Down via Scheduler - if [ "$FourBandCustom55624" == "True" ]; then - if [ ! -z $($timeoutcmd$timeoutsec nvram get wl0_sched_v2) ]; then w5udsched="Scheduler[+]"; else w5udsched="Scheduler[-]"; fi - if [ ! -z $($timeoutcmd$timeoutsec nvram get wl1_sched_v2) ]; then w52udsched="Scheduler[+]"; else w52udsched="Scheduler[-]"; fi - if [ ! -z $($timeoutcmd$timeoutsec nvram get wl2_sched_v2) ]; then w6udsched="Scheduler[+]"; else w6udsched="Scheduler[-]"; fi - if [ ! -z $($timeoutcmd$timeoutsec nvram get wl3_sched_v2) ]; then w24udsched="Scheduler[+]"; else w24udsched="Scheduler[-]"; fi - elif [ "$FourBandCustom56624" == "True" ]; then - if [ ! -z $($timeoutcmd$timeoutsec nvram get wl0_sched_v2) ]; then w5udsched="Scheduler[+]"; else w5udsched="Scheduler[-]"; fi - if [ ! -z $($timeoutcmd$timeoutsec nvram get wl1_sched_v2) ]; then w6udsched="Scheduler[+]"; else w6udsched="Scheduler[-]"; fi - if [ ! -z $($timeoutcmd$timeoutsec nvram get wl2_sched_v2) ]; then w62udsched="Scheduler[+]"; else w62udsched="Scheduler[-]"; fi - if [ ! -z $($timeoutcmd$timeoutsec nvram get wl3_sched_v2) ]; then w24udsched="Scheduler[+]"; else w24udsched="Scheduler[-]"; fi - elif [ "$ThreeBand2456" == "True" ]; then - if [ ! -z $($timeoutcmd$timeoutsec nvram get wl0_sched_v2) ]; then w24udsched="Scheduler[+]"; else w24udsched="Scheduler[-]"; fi - if [ ! -z $($timeoutcmd$timeoutsec nvram get wl1_sched_v2) ]; then w5udsched="Scheduler[+]"; else w5udsched="Scheduler[-]"; fi - if [ ! -z $($timeoutcmd$timeoutsec nvram get wl2_sched_v2) ]; then w6udsched="Scheduler[+]"; else w6udsched="Scheduler[-]"; fi - elif [ "$ThreeBand2455" == "True" ]; then - if [ ! -z $($timeoutcmd$timeoutsec nvram get wl0_sched_v2) ]; then w24udsched="Scheduler[+]"; else w24udsched="Scheduler[-]"; fi - if [ ! -z $($timeoutcmd$timeoutsec nvram get wl1_sched_v2) ]; then w5udsched="Scheduler[+]"; else w5udsched="Scheduler[-]"; fi - if [ ! -z $($timeoutcmd$timeoutsec nvram get wl2_sched_v2) ]; then w52udsched="Scheduler[+]"; else w52udsched="Scheduler[-]"; fi - else - if [ ! -z $($timeoutcmd$timeoutsec nvram get wl0_sched_v2) ]; then w24udsched="Scheduler[+]"; else w24udsched="Scheduler[-]"; fi - if [ ! -z $($timeoutcmd$timeoutsec nvram get wl1_sched_v2) ]; then w5udsched="Scheduler[+]"; else w5udsched="Scheduler[-]"; fi - fi - - w24updown=$($timeoutcmd$timeoutsec wl -i $ifname24 bss | awk '{print toupper($1)}' ) >/dev/null 2>&1 - w5updown=$($timeoutcmd$timeoutsec wl -i $ifname5 bss | awk '{print toupper($1)}' ) >/dev/null 2>&1 - if [ -z "$w24updown" ]; then w24updown="UP"; fi - if [ -z "$w5updown" ]; then w5updown="UP"; fi - - # Tri or Quad Band 5GHz - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then - w52updown=$($timeoutcmd$timeoutsec wl -i $ifname52 bss | awk '{print toupper($1)}' ) >/dev/null 2>&1 - if [ -z "$w52updown" ]; then w52updown="UP"; fi - fi - # Tri or Quad-Band 6GHz - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then - w6updown=$($timeoutcmd$timeoutsec wl -i $ifname6 bss | awk '{print toupper($1)}' ) >/dev/null 2>&1 - if [ -z $w6updown ]; then w6updown="UP"; fi - fi - if [ "$FourBandCustom56624" == "True" ]; then - w62updown=$($timeoutcmd$timeoutsec wl -i $ifname62 bss | awk '{print toupper($1)}' ) >/dev/null 2>&1 - if [ -z $w62updown ]; then w62updown="UP"; fi - fi - - # Network - Wifi - Traffic - # Standard Dual Band - new24rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname24/statistics/rx_bytes)" - new24txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname24/statistics/tx_bytes)" - new5rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname5/statistics/rx_bytes)" - new5txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname5/statistics/tx_bytes)" - - # Tri or Quad Band 5GHz - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ] - then - new52rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname52/statistics/rx_bytes)" - new52txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname52/statistics/tx_bytes)" - fi - # Tri or Quad Band 6GHz - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ] - then - new6rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname6/statistics/rx_bytes)" - new6txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname6/statistics/tx_bytes)" - fi - if [ "$FourBandCustom56624" == "True" ] - then - new62rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname62/statistics/rx_bytes)" - new62txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname62/statistics/tx_bytes)" - fi - - # Network - LAN - Traffic - newlanrxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/br0/statistics/rx_bytes)" - newlantxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/br0/statistics/tx_bytes)" - - # Network - WAN - Traffic - if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ] - then - if [ $WANOverride == "Auto" ]; then WANIFNAME=$(get_wan_setting ifname); else WANIFNAME=$WANOverride; fi - newwanrxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$WANIFNAME/statistics/rx_bytes)" - newwantxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$WANIFNAME/statistics/tx_bytes)" - fi - - # Grab total bytes VPN Traffic Measurement - if [ "$vpn1on" == "True" ]; then - newvpntxrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn1slot/status 2>/dev/null) - newvpnrxbytes="$(echo $newvpntxrxbytes | cut -d' ' -f1)" - newvpntxbytes="$(echo $newvpntxrxbytes | cut -d' ' -f2)" - if [ -z $newvpnrxbytes ]; then newvpnrxbytes=0; fi - if [ -z $newvpntxbytes ]; then newvpntxbytes=0; fi - - if [ $newvpnrxbytes -le 0 ]; then - newvpnrxbytes=0 - elif [ $newvpntxbytes -le 0 ]; then - newvpntxbytes=0 - fi - fi - - if [ "$vpn2on" == "True" ]; then - newvpn2txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn2slot/status 2>/dev/null) - newvpn2rxbytes="$(echo $newvpn2txrxbytes | cut -d' ' -f1)" - newvpn2txbytes="$(echo $newvpn2txrxbytes | cut -d' ' -f2)" - if [ -z $newvpn2rxbytes ]; then newvpn2rxbytes=0; fi - if [ -z $newvpn2txbytes ]; then newvpn2txbytes=0; fi - - if [ $newvpn2rxbytes -le 0 ]; then - newvpn2rxbytes=0 - elif [ $newvpn2txbytes -le 0 ]; then - newvpn2txbytes=0 - fi - fi - - if [ "$vpn3on" == "True" ]; then - newvpn3txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn3slot/status 2>/dev/null) - newvpn3rxbytes="$(echo $newvpn3txrxbytes | cut -d' ' -f1)" - newvpn3txbytes="$(echo $newvpn3txrxbytes | cut -d' ' -f2)" - if [ -z $newvpn3rxbytes ]; then newvpn3rxbytes=0; fi - if [ -z $newvpn3txbytes ]; then newvpn3txbytes=0; fi - - if [ $newvpn3rxbytes -le 0 ]; then - newvpn3rxbytes=0 - elif [ $newvpn3txbytes -le 0 ]; then - newvpn3txbytes=0 - fi - fi - - if [ "$vpn4on" == "True" ]; then - newvpn4txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn4slot/status 2>/dev/null) - newvpn4rxbytes="$(echo $newvpn4txrxbytes | cut -d' ' -f1)" - newvpn4txbytes="$(echo $newvpn4txrxbytes | cut -d' ' -f2)" - if [ -z $newvpn4rxbytes ]; then newvpn4rxbytes=0; fi - if [ -z $newvpn4txbytes ]; then newvpn4txbytes=0; fi - - if [ $newvpn4rxbytes -le 0 ]; then - newvpn4rxbytes=0 - elif [ $newvpn4txbytes -le 0 ]; then - newvpn4txbytes=0 - fi - fi - - if [ "$vpn5on" == "True" ]; then - newvpn5txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn5slot/status 2>/dev/null) - newvpn5rxbytes="$(echo $newvpn5txrxbytes | cut -d' ' -f1)" - newvpn5txbytes="$(echo $newvpn5txrxbytes | cut -d' ' -f2)" - if [ -z $newvpn5rxbytes ]; then newvpn5rxbytes=0; fi - if [ -z $newvpn5txbytes ]; then newvpn5txbytes=0; fi - - if [ $newvpn5rxbytes -le 0 ]; then - newvpn5rxbytes=0 - elif [ $newvpn5txbytes -le 0 ]; then - newvpn5txbytes=0 - fi - fi - - # Check the wireguard connections - if [ "$wg1on" == "True" ]; then - newwg1txrxbytes=$(wg show wgc1 transfer) - newwg1rxbytes="$(echo $newwg1txrxbytes | cut -d' ' -f3)" - newwg1txbytes="$(echo $newwg1txrxbytes | cut -d' ' -f2)" - if [ -z $newwg1rxbytes ] || [ $newwg1rxbytes -le 0 ]; then newwg1rxbytes=0; fi - if [ -z $newwg1txbytes ] || [ $newwg1txbytes -le 0 ]; then newwg1txbytes=0; fi - fi - - if [ "$wg2on" == "True" ]; then - newwg2txrxbytes=$(wg show wgc2 transfer) - newwg2rxbytes="$(echo $newwg2txrxbytes | cut -d' ' -f3)" - newwg2txbytes="$(echo $newwg2txrxbytes | cut -d' ' -f2)" - if [ -z $newwg2rxbytes ] || [ $newwg2rxbytes -le 0 ]; then newwg2rxbytes=0; fi - if [ -z $newwg2txbytes ] || [ $newwg2txbytes -le 0 ]; then newwg2txbytes=0; fi - fi - - if [ "$wg3on" == "True" ]; then - newwg3txrxbytes=$(wg show wgc3 transfer) - newwg3rxbytes="$(echo $newwg3txrxbytes | cut -d' ' -f3)" - newwg3txbytes="$(echo $newwg3txrxbytes | cut -d' ' -f2)" - if [ -z $newwg3rxbytes ] || [ $newwg3rxbytes -le 0 ]; then newwg3rxbytes=0; fi - if [ -z $newwg3txbytes ] || [ $newwg3txbytes -le 0 ]; then newwg3txbytes=0; fi - fi - - if [ "$wg4on" == "True" ]; then - newwg4txrxbytes=$(wg show wgc4 transfer) - newwg4rxbytes="$(echo $newwg4txrxbytes | cut -d' ' -f3)" - newwg4txbytes="$(echo $newwg4txrxbytes | cut -d' ' -f2)" - if [ -z $newwg4rxbytes ] || [ $newwg4rxbytes -le 0 ]; then newwg4rxbytes=0; fi - if [ -z $newwg4txbytes ] || [ $newwg4txbytes -le 0 ]; then newwg4txbytes=0; fi - fi - - if [ "$wg5on" == "True" ]; then - newwg5txrxbytes=$(wg show wgc5 transfer) - newwg5rxbytes="$(echo $newwg5txrxbytes | cut -d' ' -f3)" - newwg5txbytes="$(echo $newwg5txrxbytes | cut -d' ' -f2)" - if [ -z $newwg5rxbytes ] || [ $newwg5rxbytes -le 0 ]; then newwg5rxbytes=0; fi - if [ -z $newwg5txbytes ] || [ $newwg5txbytes -le 0 ]; then newwg5txbytes=0; fi - fi - - # Network - Traffic - Calculations to find the difference between old and new total bytes send/received and divided to give Megabits - if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then - diffwanrxbytes=$(awk -v new=$newwanrxbytes -v old=$oldwanrxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - diffwantxbytes=$(awk -v new=$newwantxbytes -v old=$oldwantxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - fi - diff24rxbytes=$(awk -v new=$new24rxbytes -v old=$old24rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - diff24txbytes=$(awk -v new=$new24txbytes -v old=$old24txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - diff5rxbytes=$(awk -v new=$new5rxbytes -v old=$old5rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - diff5txbytes=$(awk -v new=$new5txbytes -v old=$old5txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - difflanrxbytes=$(awk -v new=$newlanrxbytes -v old=$oldlanrxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - difflantxbytes=$(awk -v new=$newlantxbytes -v old=$oldlantxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then - diff52rxbytes=$(awk -v new=$new52rxbytes -v old=$old52rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - diff52txbytes=$(awk -v new=$new52txbytes -v old=$old52txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - fi - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then - diff6rxbytes=$(awk -v new=$new6rxbytes -v old=$old6rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - diff6txbytes=$(awk -v new=$new6txbytes -v old=$old6txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - fi - if [ "$FourBandCustom56624" == "True" ]; then - diff62rxbytes=$(awk -v new=$new62rxbytes -v old=$old62rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - diff62txbytes=$(awk -v new=$new62txbytes -v old=$old62txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - fi - if [ "$vpn1on" == "True" ]; then - diffvpnrxbytes=$(awk -v new=$newvpnrxbytes -v old=$oldvpnrxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - diffvpntxbytes=$(awk -v new=$newvpntxbytes -v old=$oldvpntxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - fi - if [ "$vpn2on" == "True" ]; then - diffvpn2rxbytes=$(awk -v new=$newvpn2rxbytes -v old=$oldvpn2rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - diffvpn2txbytes=$(awk -v new=$newvpn2txbytes -v old=$oldvpn2txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - fi - if [ "$vpn3on" == "True" ]; then - diffvpn3rxbytes=$(awk -v new=$newvpn3rxbytes -v old=$oldvpn3rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - diffvpn3txbytes=$(awk -v new=$newvpn3txbytes -v old=$oldvpn3txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - fi - if [ "$vpn4on" == "True" ]; then - diffvpn4rxbytes=$(awk -v new=$newvpn4rxbytes -v old=$oldvpn4rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - diffvpn4txbytes=$(awk -v new=$newvpn4txbytes -v old=$oldvpn4txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - fi - if [ "$vpn5on" == "True" ]; then - diffvpn5rxbytes=$(awk -v new=$newvpn5rxbytes -v old=$oldvpn5rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - diffvpn5txbytes=$(awk -v new=$newvpn5txbytes -v old=$oldvpn5txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - fi - if [ "$wg1on" == "True" ]; then - diffwg1rxbytes=$(awk -v new=$newwg1rxbytes -v old=$oldwg1rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - diffwg1txbytes=$(awk -v new=$newwg1txbytes -v old=$oldwg1txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - fi - if [ "$wg2on" == "True" ]; then - diffwg2rxbytes=$(awk -v new=$newwg2rxbytes -v old=$oldwg2rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - diffwg2txbytes=$(awk -v new=$newwg2txbytes -v old=$oldwg2txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - fi - if [ "$wg3on" == "True" ]; then - diffwg3rxbytes=$(awk -v new=$newwg3rxbytes -v old=$oldwg3rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - diffwg3txbytes=$(awk -v new=$newwg3txbytes -v old=$oldwg3txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - fi - if [ "$wg4on" == "True" ]; then - diffwg4rxbytes=$(awk -v new=$newwg4rxbytes -v old=$oldwg4rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - diffwg4txbytes=$(awk -v new=$newwg4txbytes -v old=$oldwg4txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - fi - if [ "$wg5on" == "True" ]; then - diffwg5rxbytes=$(awk -v new=$newwg5rxbytes -v old=$oldwg5rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - diffwg5txbytes=$(awk -v new=$newwg5txbytes -v old=$oldwg5txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') - fi - - # Network - Traffic - Results are further divided by the timer/interval to give Megabits/sec - if [ "$WAN0AltModes" = "0" ] || [ "$OpsMode" = "1" ] - then - wanrxmbrate=$(awk -v rb=$diffwanrxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) - wantxmbrate=$(awk -v tb=$diffwantxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) - else - wanrxmbrate=0 - wantxmbrate=0 - fi - - w24rxmbrate=$(awk -v rb=$diff24rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) - w24txmbrate=$(awk -v tb=$diff24txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) - w5rxmbrate=$(awk -v rb=$diff5rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) - w5txmbrate=$(awk -v tb=$diff5txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) - lanrxmbrate=$(awk -v rb=$difflanrxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) - lantxmbrate=$(awk -v tb=$difflantxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) - - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ] - then - w52rxmbrate=$(awk -v rb=$diff52rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) - w52txmbrate=$(awk -v tb=$diff52txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) - else - w52rxmbrate=0 - w52txmbrate=0 - fi - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ] - then - w6rxmbrate=$(awk -v rb=$diff6rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) - w6txmbrate=$(awk -v tb=$diff6txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) - else - w6rxmbrate=0 - w6txmbrate=0 - fi - if [ "$FourBandCustom56624" == "True" ] - then - w62rxmbrate=$(awk -v rb=$diff62rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) - w62txmbrate=$(awk -v tb=$diff62txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) - else - w62rxmbrate=0 - w62txmbrate=0 - fi - if [ "$vpn1on" == "True" ] - then - vpnrxmbrate=$(awk -v rb=$diffvpnrxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) - vpntxmbrate=$(awk -v tb=$diffvpntxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) - else - vpnrxmbrate=0 - vpntxmbrate=0 - fi - if [ "$vpn2on" == "True" ] - then - vpn2rxmbrate=$(awk -v rb=$diffvpn2rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) - vpn2txmbrate=$(awk -v tb=$diffvpn2txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) - else - vpn2rxmbrate=0 - vpn2txmbrate=0 - fi - if [ "$vpn3on" == "True" ] - then - vpn3rxmbrate=$(awk -v rb=$diffvpn3rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) - vpn3txmbrate=$(awk -v tb=$diffvpn3txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) - else - vpn3rxmbrate=0 - vpn3txmbrate=0 - fi - if [ "$vpn4on" == "True" ] - then - vpn4rxmbrate=$(awk -v rb=$diffvpn4rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) - vpn4txmbrate=$(awk -v tb=$diffvpn4txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) - else - vpn4rxmbrate=0 - vpn4txmbrate=0 - fi - if [ "$vpn5on" == "True" ] - then - vpn5rxmbrate=$(awk -v rb=$diffvpn5rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) - vpn5txmbrate=$(awk -v tb=$diffvpn5txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) - else - vpn5rxmbrate=0 - vpn5txmbrate=0 - fi - if [ "$wg1on" == "True" ] - then - wg1rxmbrate=$(awk -v rb=$diffwg1rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) - wg1txmbrate=$(awk -v tb=$diffwg1txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) - else - wg1rxmbrate=0 - wg1txmbrate=0 - fi - if [ "$wg2on" == "True" ] - then - wg2rxmbrate=$(awk -v rb=$diffwg2rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) - wg2txmbrate=$(awk -v tb=$diffwg2txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) - else - wg2rxmbrate=0 - wg2txmbrate=0 - fi - if [ "$wg3on" == "True" ] - then - wg3rxmbrate=$(awk -v rb=$diffwg3rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) - wg3txmbrate=$(awk -v tb=$diffwg3txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) - else - wg3rxmbrate=0 - wg3txmbrate=0 - fi - if [ "$wg4on" == "True" ] - then - wg4rxmbrate=$(awk -v rb=$diffwg4rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) - wg4txmbrate=$(awk -v tb=$diffwg4txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) - else - wg4rxmbrate=0 - wg4txmbrate=0 - fi - if [ "$wg5on" == "True" ] - then - wg5rxmbrate=$(awk -v rb=$diffwg5rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) - wg5txmbrate=$(awk -v tb=$diffwg5txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) - else - wg5rxmbrate=0 - wg5txmbrate=0 - fi - if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ] - then - wanrxmbratedisplay=$(awk -v rb=$diffwanrxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') - wantxmbratedisplay=$(awk -v tb=$diffwantxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') - fi - - w24rxmbratedisplay=$(awk -v rb=$diff24rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') - w24txmbratedisplay=$(awk -v tb=$diff24txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') - w5rxmbratedisplay=$(awk -v rb=$diff5rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') - w5txmbratedisplay=$(awk -v tb=$diff5txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') - lanrxmbratedisplay=$(awk -v rb=$difflanrxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') - lantxmbratedisplay=$(awk -v tb=$difflantxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') - - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ] - then - w52rxmbratedisplay=$(awk -v rb=$diff52rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') - w52txmbratedisplay=$(awk -v tb=$diff52txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') - else - w52rxmbratedisplay="" - w52txmbratedisplay="" - fi - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ] - then - w6rxmbratedisplay=$(awk -v rb=$diff6rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') - w6txmbratedisplay=$(awk -v tb=$diff6txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') - else - w6rxmbratedisplay="" - w6txmbratedisplay="" - fi - if [ "$FourBandCustom56624" == "True" ] - then - w62rxmbratedisplay=$(awk -v rb=$diff62rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') - w62txmbratedisplay=$(awk -v tb=$diff62txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') - else - w62rxmbratedisplay="" - w62txmbratedisplay="" - fi - if [ "$vpn1on" == "True" ] - then - vpnrxmbratedisplay=$(awk -v rb=$diffvpnrxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') - vpntxmbratedisplay=$(awk -v tb=$diffvpntxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') - else - vpnrxmbratedisplay="" - vpntxmbratedisplay="" - fi - if [ "$vpn2on" == "True" ] - then - vpn2rxmbratedisplay=$(awk -v rb=$diffvpn2rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') - vpn2txmbratedisplay=$(awk -v tb=$diffvpn2txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') - else - vpn2rxmbratedisplay="" - vpn2txmbratedisplay="" - fi - if [ "$vpn3on" == "True" ] - then - vpn3rxmbratedisplay=$(awk -v rb=$diffvpn3rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') - vpn3txmbratedisplay=$(awk -v tb=$diffvpn3txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') - else - vpn3rxmbratedisplay="" - vpn3txmbratedisplay="" - fi - if [ "$vpn4on" == "True" ] - then - vpn4rxmbratedisplay=$(awk -v rb=$diffvpn4rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') - vpn4txmbratedisplay=$(awk -v tb=$diffvpn4txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') - else - vpn4rxmbratedisplay="" - vpn4txmbratedisplay="" - fi - if [ "$vpn5on" == "True" ] - then - vpn5rxmbratedisplay=$(awk -v rb=$diffvpn5rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') - vpn5txmbratedisplay=$(awk -v tb=$diffvpn5txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') - else - vpn5rxmbratedisplay="" - vpn5txmbratedisplay="" - fi - if [ "$wg1on" == "True" ] - then - wg1rxmbratedisplay=$(awk -v rb=$diffwg1rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') - wg1txmbratedisplay=$(awk -v tb=$diffwg1txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') - else - wg1rxmbratedisplay="" - wg1txmbratedisplay="" - fi - if [ "$wg2on" == "True" ] - then - wg2rxmbratedisplay=$(awk -v rb=$diffwg2rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') - wg2txmbratedisplay=$(awk -v tb=$diffwg2txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') - else - wg2rxmbratedisplay="" - wg2txmbratedisplay="" - fi - if [ "$wg3on" == "True" ] - then - wg3rxmbratedisplay=$(awk -v rb=$diffwg3rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') - wg3txmbratedisplay=$(awk -v tb=$diffwg3txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') - else - wg3rxmbratedisplay="" - wg3txmbratedisplay="" - fi - if [ "$wg4on" == "True" ] - then - wg4rxmbratedisplay=$(awk -v rb=$diffwg4rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') - wg4txmbratedisplay=$(awk -v tb=$diffwg4txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') - else - wg4rxmbratedisplay="" - wg4txmbratedisplay="" - fi - if [ "$wg5on" == "True" ] - then - wg5rxmbratedisplay=$(awk -v rb=$diffwg5rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') - wg5txmbratedisplay=$(awk -v tb=$diffwg5txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') - else - wg5rxmbratedisplay="" - wg5txmbratedisplay="" - fi - - # Uptime calc # - uptimeStr="$(awk '{printf("%3dd %02dh %02dm %02ds\n",($1/60/60/24),($1/60/60%24),($1/60%60),($1%60))}' /proc/uptime)" - -} - -# ------------------------------------------------------------------------------------------------------------------------- - -# This function displays the stats UI for page 1 -DisplayPage1() -{ - - clear - if [ "$UpdateNotify" != "0" ]; then - echo -e "$UpdateNotify${CClear}" - fi - showheader - echo "" - echo -e "${InvDkGray}${CWhite} CPU ${CClear}" - echo "" - echo -e "${InvGreen} ${CClear} ${CWhite}Uptime ${CDkGray}[ ${CWhite}$uptimeStr${CDkGray} ]${CClear}" - echo -e "${InvGreen} ${CClear} ${CWhite}CPU Load ${CDkGray}[ ${CGreen}1m: ${CWhite}$cpuload1m ${CGreen}5m: ${CWhite}$cpuload5m ${CGreen}15m: ${CWhite}$cpuload15m${CDkGray} ]${CClear}" - preparebar 79 "|" - progressbar $oldcpuusr1 100 " CPU User " "%%" "Standard" $olddisplaycpuusr1 - echo "" - preparebar 79 "|" - progressbar $oldcpusys1 100 " CPU System" "%%" "Standard" $olddisplaycpusys1 - echo "" - preparebar 79 "|" - progressbar $oldcpunice1 100 " CPU Nice " "%%" "Standard" $olddisplaycpunice1 - echo "" - preparebar 79 "|" - progressbar $oldcpuidle1 100 " CPU Idle " "%%" "Reverse" $olddisplaycpuidle1 - echo "" - preparebar 79 "|" - progressbar $oldcpuirq1 100 " CPU IRQ " "%%" "Standard" $olddisplaycpuirq1 - echo "" - preparebar 79 "|" - converttemps $oldF_cputemp - progressbar $currenttemp $currentrange " CPU Temp " $TempUnits "CPU" $currenttemp $currentrange - echo "" - echo "" - echo -e "${InvDkGray}${CWhite} Memory ${CClear}" - echo "" - echo -en "${InvGreen} ${CClear} ${CWhite}Mem Total ${CDkGray}[ ${CWhite}" - printf "%-7s" "$totalphysmem MB" - echo -e "${CDkGray} ]${CClear}" - preparebar 79 "|" - progressbar $oldmemused2 $oldtotalmemory " Mem Used " "MB" "Standard" - echo "" - preparebar 79 "|" - progressbar $oldmemfree2 $oldtotalmemory " Mem Free " "MB" "Reverse" - echo "" - preparebar 79 "|" - progressbar $oldmemshrd2 $oldtotalmemory " Mem Shared" "MB" "Standard" - echo "" - preparebar 79 "|" - progressbar $oldmembuff2 $oldtotalmemory " Mem Buffer" "MB" "Standard" - echo "" - preparebar 79 "|" - progressbar $oldmemcach2 $oldtotalmemory " Mem Cache " "MB" "Standard" - echo "" - preparebar 79 "|" - progressbar $oldnvramused $oldtotalnvram " NVRAM Used" "B" "Standard" - echo "" - echo "" - echo -e "${InvDkGray}${CWhite} Disk ${CClear}" - echo "" - echo -en "${InvGreen} ${CClear} ${CWhite}Swap Size ${CDkGray}[ ${CWhite}" - printf "%-8s" "$swaptotal MB" - echo -e "${CDkGray} ]${CClear}" - preparebar 79 "|" - progressbar $oldswapused $oldswaptotal " Swap Used " "MB" "Standard" - echo "" - preparebar 79 "|" - progressbar $oldjffsused $oldjffstotal " JFFS Used " "MB" "Standard" - - #Disk - SD devices - if [ -s /jffs/addons/rtrmon.d/sdresult.txt ] - then - sdcnt=$(cat /jffs/addons/rtrmon.d/sdresult.txt | wc -l) >/dev/null 2>&1 - if [ -z "$sdcnt" ] || [ $sdcnt -lt 1 ]; then - sdcnt=0 - fi - else - sdcnt=0 - fi - - CNT=0 - while [ "$CNT" -lt "$sdcnt" ] # Loop through number of /dev/sd*'s # - do - CNT="$((CNT+1))" - dfresults="$(sed -n "${CNT}p" /jffs/addons/rtrmon.d/sdresult.txt)" - if [ -z "$dfresults" ]; then break; fi - sdname="$(echo $dfresults | awk '{print $1}')" - sdtotal="$(echo $dfresults | awk '{print $2}')" - sdused="$(echo $dfresults | awk '{print $3}')" - - sdtotal=$(echo "$sdtotal 1048576" | awk '{print $1/$2}' | cut -d . -f 1) - sdused=$(echo "$sdused 1048576" | awk '{print $1/$2}' | cut -d . -f 1) - if [ $sdtotal == "0" ]; then sdtotal=1; fi - if [ $sdused == "0" ]; then sdused=1; fi - sdnameformat=$(printf "%-10s" $sdname) - - echo "" - preparebar 79 "|" - progressbar $sdused $sdtotal " $sdnameformat" "GB" "Standard" - done -} - -# ------------------------------------------------------------------------------------------------------------------------- - -# This function displays the stats UI for page 2 -DisplayPage2() -{ - clear - if [ "$UpdateNotify" != "0" ]; then - echo -e "$UpdateNotify${CClear}" - fi - showheader - if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then - echo "" - echo -e "${InvDkGray}${CWhite} WAN ${CClear}" - echo "" - if [ "$ScreenshotMode" == "1" ]; then - oldwan0ip="1.2.3.4" #demo - oldwanip6="abc1:23de::f456:ghi7:89jk:l0mn:opqr" #demo - oldvpn1ip="2.3.4.5" #demo - oldvpn2ip="3.4.5.6" #demo - oldvpn3ip="4.5.6.7" #demo - oldvpn4ip="5.6.7.8" #demo - oldvpn5ip="6.7.8.9" #demo - oldwg1ip="2.3.4.5" #demo - oldwg2ip="3.4.5.6" #demo - oldwg3ip="4.5.6.7" #demo - oldwg4ip="5.6.7.8" #demo - oldwg5ip="6.7.8.9" #demo - oldvpn1city="Rivendell" #demo - oldvpn2city="Mordor" #demo - oldvpn3city="Minas Tirith" #demo - oldvpn4city="Edoras" #demo - oldvpn5city="Aglarond" #demo - oldwg1city="Rivendell" #demo - oldwg2city="Mordor" #demo - oldwg3city="Minas Tirith" #demo - oldwg4city="Edoras" #demo - oldwg5city="Aglarond" #demo - fi - echo -en "${InvGreen} ${CClear} ${CWhite}WAN 0/1 IP ${CDkGray}[ ${CWhite}" - printf '%03d.%03d.%03d.%03d' ${oldwan0ip//./ } - echo -en " / " - printf '%03d.%03d.%03d.%03d' ${oldwan1ip//./ } - echo -en "${CDkGray} ] ${CWhite} DNS ${CDkGray}[ ${CWhite}" - if [ $olddns1ip = "0.0.0.0" ]; then printf "000.000.000.000"; else printf '%03d.%03d.%03d.%03d' ${olddns1ip//./ }; fi - echo -en " / " - if [ $olddns2ip = "0.0.0.0" ]; then printf "000.000.000.000"; else printf '%03d.%03d.%03d.%03d' ${olddns2ip//./ }; fi - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}IFace: $WANIFNAME${CClear}" - if [ ! -z $oldwanip6 ]; then echo -e "${InvGreen} ${CClear} ${CWhite}WAN 0/1 I6 ${CDkGray}[ ${CWhite}$oldwanip6${CClear}"; fi - preparebar 79 "|" - progressbar $oldwanrxmbrate $MaxSpeedInet " Avg WAN RX" "Mbps" "Standard" $oldwanrxmbratedisplay $MaxSpeedInet - echo "" - preparebar 79 "|" - progressbar $oldwantxmbrate $MaxSpeedInetUL " Avg WAN TX" "Mbps" "Standard" $oldwantxmbratedisplay $MaxSpeedInetUL - echo "" - fi - echo "" - echo -e "${InvDkGray}${CWhite} LAN ${CClear}" - echo "" - echo -en "${InvGreen} ${CClear}${CWhite} BR0 LAN IP ${CDkGray}[ ${CWhite}" - printf '%03d.%03d.%03d.%03d' ${oldlanip//./ } - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}IFace: br0${CClear}" - if [ ! -z $oldlanip6 ]; then echo -e "${InvGreen} ${CClear} ${CWhite}BR0 LAN I6 ${CDkGray}[ ${CWhite}$oldlanip6${CClear}"; fi - - preparebar 79 "|" - progressbar $oldlanrxmbrate $MaxSpeedLAN " Avg LAN RX" "Mbps" "Standard" $oldlanrxmbratedisplay $MaxSpeedLAN - echo "" - preparebar 79 "|" - if [ ${oldlantxmbrate%.*} -lt 0 ]; then oldlantxmbrate=0; oldlantxmbratedisplay=0; fi - progressbar $oldlantxmbrate $MaxSpeedLAN " Avg LAN TX" "Mbps" "Standard" $oldlantxmbratedisplay $MaxSpeedLAN - - if [ "$vpn1on" == "True" ]; then - echo "" - echo "" - echo -e "${InvDkGray}${CWhite} OVPN$vpn1slot ${CClear}" - echo "" - if [ "$oldvpn1city" == "Private Network" ]; then - echo -en "${InvGreen} ${CClear}${CWhite} PRV VPN IP ${CDkGray}[ ${CWhite}" - printf '%03d.%03d.%03d.%03d' ${oldvpn1ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" - - printf "%-33s" "$oldvpn1city" - - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn1slot${CClear}" - else - echo -en "${InvGreen} ${CClear}${CWhite} PUB VPN IP ${CDkGray}[ ${CWhite}" - printf '%03d.%03d.%03d.%03d' ${oldvpn1ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" - - printf "%-33s" "$oldvpn1city" - - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn1slot${CClear}" - fi - if [ ${oldvpntxmbrate%.*} -lt 0 ]; then oldvpntxmbrate=0; oldvpntxmbratedisplay=0; fi - preparebar 79 "|" - progressbar $oldvpntxmbrate $MaxSpeedInet " Avg VPN RX" "Mbps" "Standard" $oldvpntxmbratedisplay $MaxSpeedInet - echo "" - if [ ${oldvpnrxmbrate%.*} -lt 0 ]; then oldvpnrxmbrate=0; oldvpnrxmbratedisplay=0; fi - preparebar 79 "|" - progressbar $oldvpnrxmbrate $MaxSpeedInetUL " Avg VPN TX" "Mbps" "Standard" $oldvpnrxmbratedisplay $MaxSpeedInetUL - fi - - if [ "$vpn2on" == "True" ]; then - echo "" - echo "" - echo -e "${InvDkGray}${CWhite} OVPN$vpn2slot ${CClear}" - echo "" - if [ "$oldvpn2city" == "Private Network" ]; then - echo -en "${InvGreen} ${CClear}${CWhite} PRV VPN IP ${CDkGray}[ ${CWhite}" - printf '%03d.%03d.%03d.%03d' ${oldvpn2ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" - - printf "%-33s" "$oldvpn2city" - - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn2slot${CClear}" - else - echo -en "${InvGreen} ${CClear}${CWhite} PUB VPN IP ${CDkGray}[ ${CWhite}" - printf '%03d.%03d.%03d.%03d' ${oldvpn2ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" - - printf "%-33s" "$oldvpn2city" - - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn2slot${CClear}" - fi - if [ ${oldvpn2txmbrate%.*} -lt 0 ]; then oldvpn2txmbrate=0; oldvpn2txmbratedisplay=0; fi - preparebar 79 "|" - progressbar $oldvpn2txmbrate $MaxSpeedInet " Avg VPN RX" "Mbps" "Standard" $oldvpn2txmbratedisplay $MaxSpeedInet - echo "" - if [ ${oldvpn2rxmbrate%.*} -lt 0 ]; then oldvpn2rxmbrate=0; oldvpn2rxmbratedisplay=0; fi - preparebar 79 "|" - progressbar $oldvpn2rxmbrate $MaxSpeedInetUL " Avg VPN TX" "Mbps" "Standard" $oldvpn2rxmbratedisplay $MaxSpeedInetUL - fi - - if [ "$vpn3on" == "True" ]; then - echo "" - echo "" - echo -e "${InvDkGray}${CWhite} OVPN$vpn3slot ${CClear}" - echo "" - if [ "$oldvpn3city" == "Private Network" ]; then - echo -en "${InvGreen} ${CClear}${CWhite} PRV VPN IP ${CDkGray}[ ${CWhite}" - printf '%03d.%03d.%03d.%03d' ${oldvpn3ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" - - printf "%-33s" "$oldvpn3city" - - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn3slot${CClear}" - else - echo -en "${InvGreen} ${CClear}${CWhite} PUB VPN IP ${CDkGray}[ ${CWhite}" - printf '%03d.%03d.%03d.%03d' ${oldvpn3ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" - - printf "%-33s" "$oldvpn3city" - - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn3slot${CClear}" - fi - if [ ${oldvpn3txmbrate%.*} -lt 0 ]; then oldvpn3txmbrate=0; oldvpn3txmbratedisplay=0; fi - preparebar 79 "|" - progressbar $oldvpn3txmbrate $MaxSpeedInet " Avg VPN RX" "Mbps" "Standard" $oldvpn3txmbratedisplay $MaxSpeedInet - echo "" - if [ ${oldvpn3rxmbrate%.*} -lt 0 ]; then oldvpn3rxmbrate=0; oldvpn3rxmbratedisplay=0; fi - preparebar 79 "|" - progressbar $oldvpn3rxmbrate $MaxSpeedInetUL " Avg VPN TX" "Mbps" "Standard" $oldvpn3rxmbratedisplay $MaxSpeedInetUL - fi - - if [ "$vpn4on" == "True" ]; then - echo "" - echo "" - echo -e "${InvDkGray}${CWhite} OVPN$vpn4slot ${CClear}" - echo "" - if [ "$oldvpn4city" == "Private Network" ]; then - echo -en "${InvGreen} ${CClear}${CWhite} PRV VPN IP ${CDkGray}[ ${CWhite}" - printf '%03d.%03d.%03d.%03d' ${oldvpn4ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" - - printf "%-33s" "$oldvpn4city" - - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn4slot${CClear}" - else - echo -en "${InvGreen} ${CClear}${CWhite} PUB VPN IP ${CDkGray}[ ${CWhite}" - printf '%03d.%03d.%03d.%03d' ${oldvpn4ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" - - printf "%-33s" "$oldvpn4city" - - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn4slot${CClear}" - fi - if [ ${oldvpn4txmbrate%.*} -lt 0 ]; then oldvpn4txmbrate=0; oldvpn4txmbratedisplay=0; fi - preparebar 79 "|" - progressbar $oldvpn4txmbrate $MaxSpeedInet " Avg VPN RX" "Mbps" "Standard" $oldvpn4txmbratedisplay $MaxSpeedInet - echo "" - if [ ${oldvpn4rxmbrate%.*} -lt 0 ]; then oldvpn4rxmbrate=0; oldvpn4rxmbratedisplay=0; fi - preparebar 79 "|" - progressbar $oldvpn4rxmbrate $MaxSpeedInetUL " Avg VPN TX" "Mbps" "Standard" $oldvpn4rxmbratedisplay $MaxSpeedInetUL - fi - - if [ "$vpn5on" == "True" ]; then - echo "" - echo "" - echo -e "${InvDkGray}${CWhite} OVPN$vpn5slot ${CClear}" - echo "" - if [ "$oldvpn5city" == "Private Network" ]; then - echo -en "${InvGreen} ${CClear}${CWhite} PRV VPN IP ${CDkGray}[ ${CWhite}" - printf '%03d.%03d.%03d.%03d' ${oldvpn5ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" - - printf "%-33s" "$oldvpn5city" - - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn5slot${CClear}" - else - echo -en "${InvGreen} ${CClear}${CWhite} PUB VPN IP ${CDkGray}[ ${CWhite}" - printf '%03d.%03d.%03d.%03d' ${oldvpn5ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" - - printf "%-33s" "$oldvpn5city" - - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn5slot${CClear}" - fi - if [ ${oldvpn5txmbrate%.*} -lt 0 ]; then oldvpn5txmbrate=0; oldvpn5txmbratedisplay=0; fi - preparebar 79 "|" - progressbar $oldvpn5txmbrate $MaxSpeedInet " Avg VPN RX" "Mbps" "Standard" $oldvpn5txmbratedisplay $MaxSpeedInet - echo "" - if [ ${oldvpn5rxmbrate%.*} -lt 0 ]; then oldvpn5rxmbrate=0; oldvpn5rxmbratedisplay=0; fi - preparebar 79 "|" - progressbar $oldvpn5rxmbrate $MaxSpeedInetUL " Avg VPN TX" "Mbps" "Standard" $oldvpn5rxmbratedisplay $MaxSpeedInetUL - fi - - if [ "$wg1on" == "True" ]; then - echo "" - echo "" - echo -e "${InvDkGray}${CWhite} WG$wg1slot ${CClear}" - echo "" - if [ "$oldwg1city" == "Private Network" ]; then - echo -en "${InvGreen} ${CClear}${CWhite} PRV WG IP ${CDkGray}[ ${CWhite}" - printf '%03d.%03d.%03d.%03d' ${oldwg1ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" - - printf "%-33s" "$oldwg1city" - - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg1slot${CClear}" - else - echo -en "${InvGreen} ${CClear}${CWhite} PUB WG IP ${CDkGray}[ ${CWhite}" - printf '%03d.%03d.%03d.%03d' ${oldwg1ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" - - printf "%-33s" "$oldwg1city" - - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg1slot${CClear}" - fi - if [ ${oldwg1txmbrate%.*} -lt 0 ]; then oldwg1txmbrate=0; oldwg1txmbratedisplay=0; fi - preparebar 79 "|" - progressbar $oldwg1txmbrate $MaxSpeedInet " Avg WG RX " "Mbps" "Standard" $oldwg1txmbratedisplay $MaxSpeedInet - echo "" - if [ ${oldwg1rxmbrate%.*} -lt 0 ]; then oldwg1rxmbrate=0; oldwg1rxmbratedisplay=0; fi - preparebar 79 "|" - progressbar $oldwg1rxmbrate $MaxSpeedInetUL " Avg WG TX " "Mbps" "Standard" $oldwg1rxmbratedisplay $MaxSpeedInetUL - fi - - if [ "$wg2on" == "True" ]; then - echo "" - echo "" - echo -e "${InvDkGray}${CWhite} WG$wg2slot ${CClear}" - echo "" - if [ "$oldwg2city" == "Private Network" ]; then - echo -en "${InvGreen} ${CClear}${CWhite} PRV WG IP ${CDkGray}[ ${CWhite}" - printf '%03d.%03d.%03d.%03d' ${oldwg2ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" - - printf "%-33s" "$oldwg2city" - - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg2slot${CClear}" - else - echo -en "${InvGreen} ${CClear}${CWhite} PUB WG IP ${CDkGray}[ ${CWhite}" - printf '%03d.%03d.%03d.%03d' ${oldwg2ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" - - printf "%-33s" "$oldwg2city" - - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg2slot${CClear}" - fi - if [ ${oldwg2txmbrate%.*} -lt 0 ]; then oldwg2txmbrate=0; oldwg2txmbratedisplay=0; fi - preparebar 79 "|" - progressbar $oldwg2txmbrate $MaxSpeedInet " Avg WG RX " "Mbps" "Standard" $oldwg2txmbratedisplay $MaxSpeedInet - echo "" - if [ ${oldwg2rxmbrate%.*} -lt 0 ]; then oldwg2rxmbrate=0; oldwg2rxmbratedisplay=0; fi - preparebar 79 "|" - progressbar $oldwg2rxmbrate $MaxSpeedInetUL " Avg WG TX " "Mbps" "Standard" $oldwg2rxmbratedisplay $MaxSpeedInetUL - fi - - if [ "$wg3on" == "True" ]; then - echo "" - echo "" - echo -e "${InvDkGray}${CWhite} WG$wg3slot ${CClear}" - echo "" - if [ "$oldwg3city" == "Private Network" ]; then - echo -en "${InvGreen} ${CClear}${CWhite} PRV WG IP ${CDkGray}[ ${CWhite}" - printf '%03d.%03d.%03d.%03d' ${oldwg3ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" - - printf "%-33s" "$oldwg3city" - - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg3slot${CClear}" - else - echo -en "${InvGreen} ${CClear}${CWhite} PUB WG IP ${CDkGray}[ ${CWhite}" - printf '%03d.%03d.%03d.%03d' ${oldwg3ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" - - printf "%-33s" "$oldwg3city" - - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg3slot${CClear}" - fi - if [ ${oldwg3txmbrate%.*} -lt 0 ]; then oldwg3txmbrate=0; oldwg3txmbratedisplay=0; fi - preparebar 79 "|" - progressbar $oldwg3txmbrate $MaxSpeedInet " Avg WG RX " "Mbps" "Standard" $oldwg3txmbratedisplay $MaxSpeedInet - echo "" - if [ ${oldwg3rxmbrate%.*} -lt 0 ]; then oldwg3rxmbrate=0; oldwg3rxmbratedisplay=0; fi - preparebar 79 "|" - progressbar $oldwg3rxmbrate $MaxSpeedInetUL " Avg WG TX " "Mbps" "Standard" $oldwg3rxmbratedisplay $MaxSpeedInetUL - fi - - if [ "$wg4on" == "True" ]; then - echo "" - echo "" - echo -e "${InvDkGray}${CWhite} WG$wg4slot ${CClear}" - echo "" - if [ "$oldwg4city" == "Private Network" ]; then - echo -en "${InvGreen} ${CClear}${CWhite} PRV WG IP ${CDkGray}[ ${CWhite}" - printf '%03d.%03d.%03d.%03d' ${oldwg4ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" - - printf "%-33s" "$oldwg4city" - - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg4slot${CClear}" - else - echo -en "${InvGreen} ${CClear}${CWhite} PUB WG IP ${CDkGray}[ ${CWhite}" - printf '%03d.%03d.%03d.%03d' ${oldwg4ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" - - printf "%-33s" "$oldwg4city" - - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg4slot${CClear}" - fi - if [ ${oldwg4txmbrate%.*} -lt 0 ]; then oldwg4txmbrate=0; oldwg4txmbratedisplay=0; fi - preparebar 79 "|" - progressbar $oldwg4txmbrate $MaxSpeedInet " Avg WG RX " "Mbps" "Standard" $oldwg4txmbratedisplay $MaxSpeedInet - echo "" - if [ ${oldwg4rxmbrate%.*} -lt 0 ]; then oldwg4rxmbrate=0; oldwg4rxmbratedisplay=0; fi - preparebar 79 "|" - progressbar $oldwg4rxmbrate $MaxSpeedInetUL " Avg WG TX " "Mbps" "Standard" $oldwg4rxmbratedisplay $MaxSpeedInetUL - fi - - if [ "$wg5on" == "True" ]; then - echo "" - echo "" - echo -e "${InvDkGray}${CWhite} WG$wg5slot ${CClear}" - echo "" - if [ "$oldwg5city" == "Private Network" ]; then - echo -en "${InvGreen} ${CClear}${CWhite} PRV WG IP ${CDkGray}[ ${CWhite}" - printf '%03d.%03d.%03d.%03d' ${oldwg5ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" - - printf "%-33s" "$oldwg5city" - - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg5slot${CClear}" - else - echo -en "${InvGreen} ${CClear}${CWhite} PUB WG IP ${CDkGray}[ ${CWhite}" - printf '%03d.%03d.%03d.%03d' ${oldwg5ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" - - printf "%-33s" "$oldwg5city" - - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg5slot${CClear}" - fi - if [ ${oldwg5txmbrate%.*} -lt 0 ]; then oldwg5txmbrate=0; oldwg5txmbratedisplay=0; fi - preparebar 79 "|" - progressbar $oldwg5txmbrate $MaxSpeedInet " Avg WG RX " "Mbps" "Standard" $oldwg5txmbratedisplay $MaxSpeedInet - echo "" - if [ ${oldwg5rxmbrate%.*} -lt 0 ]; then oldwg5rxmbrate=0; oldwg5rxmbratedisplay=0; fi - preparebar 79 "|" - progressbar $oldwg5rxmbrate $MaxSpeedInetUL " Avg WG TX " "Mbps" "Standard" $oldwg5rxmbratedisplay $MaxSpeedInetUL - fi - -} - -# ------------------------------------------------------------------------------------------------------------------------- - -# This function displays the stats UI for page 3 -DisplayPage3() -{ - clear - if [ "$UpdateNotify" != "0" ]; then - echo -e "$UpdateNotify${CClear}" - fi - showheader - # Per @Stephen Harrington's sugguestion, check NVRAM to see if Wifi is turned on, else mark them as disabled - if [ "$FourBandCustom55624" == "True" ]; then - if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then - MaxSpeed5GhzNow=0 - else - MaxSpeed5GhzNow=$MaxSpeed5Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then - MaxSpeed52GhzNow=0 - else - MaxSpeed52GhzNow=$MaxSpeed5Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then - MaxSpeed6GhzNow=0 - else - MaxSpeed6GhzNow=$MaxSpeed6Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl3_radio) -eq 0 ]; then - MaxSpeed24GhzNow=0 - else - MaxSpeed24GhzNow=$MaxSpeed24Ghz - fi - elif [ "$FourBandCustom56624" == "True" ]; then - if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then - MaxSpeed5GhzNow=0 - else - MaxSpeed5GhzNow=$MaxSpeed5Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then - MaxSpeed6GhzNow=0 - else - MaxSpeed6GhzNow=$MaxSpeed6Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then - MaxSpeed62GhzNow=0 - else - MaxSpeed62GhzNow=$MaxSpeed6Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl3_radio) -eq 0 ]; then - MaxSpeed24GhzNow=0 - else - MaxSpeed24GhzNow=$MaxSpeed24Ghz - fi - elif [ "$ThreeBand2456" == "True" ]; then - if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then - MaxSpeed24GhzNow=0 - else - MaxSpeed24GhzNow=$MaxSpeed24Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then - MaxSpeed5GhzNow=0 - else - MaxSpeed5GhzNow=$MaxSpeed5Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then - MaxSpeed6GhzNow=0 - else - MaxSpeed6GhzNow=$MaxSpeed6Ghz - fi - elif [ "$ThreeBand2455" == "True" ]; then - if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then - MaxSpeed24GhzNow=0 - else - MaxSpeed24GhzNow=$MaxSpeed24Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then - MaxSpeed5GhzNow=0 - else - MaxSpeed5GhzNow=$MaxSpeed5Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then - MaxSpeed52GhzNow=0 - else - MaxSpeed52GhzNow=$MaxSpeed5Ghz - fi - else - if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then - MaxSpeed24GhzNow=0 - else - MaxSpeed24GhzNow=$MaxSpeed24Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then - MaxSpeed5GhzNow=0 - else - MaxSpeed5GhzNow=$MaxSpeed5Ghz - fi - fi - - echo "" - echo -e "${InvDkGray}${CWhite} WiFi ${CClear}" - echo "" - if [ "$MaxSpeed24GhzNow" != "0" ]; then - if [ "$w24updown" == "UP" ]; then - echo -e "${InvGreen} ${CClear} ${CWhite}2.4GHz ${CDkGray}[ ${CWhite}Enabled - $w24udsched - UP ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname24${CClear}" - else - echo -e "${InvGreen} ${CClear} ${CWhite}2.4GHz ${CDkGray}[ ${CWhite}Enabled - $w24udsched - DOWN ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname24${CClear}" - fi - preparebar 79 "|" - progressbar $oldw24rxmbrate $MaxSpeed24GhzNow " Avg 24G RX" "Mbps" "Standard" $oldw24rxmbratedisplay $MaxSpeed24GhzNow - echo "" - preparebar 79 "|" - progressbar $oldw24txmbrate $MaxSpeed24GhzNow " Avg 24G TX" "Mbps" "Standard" $oldw24txmbratedisplay $MaxSpeed24GhzNow - echo "" - preparebar 79 "|" - converttemps $oldw24temp - progressbar $currenttemp $currentrange " 2.4G Temp " $TempUnits "Standard" $currenttemp $currentrange - else - echo -e "${InvRed} ${CClear}${CWhite} 2.4GHz ${CDkGray}[ ${CRed}Disabled ${CDkGray}]${CClear}" - fi - if [ "$MaxSpeed5GhzNow" != "0" ]; then - echo "" - echo "" - if [ "$w5updown" == "UP" ]; then - echo -e "${InvGreen} ${CClear} ${CWhite}5.0GHz ${CDkGray}[ ${CWhite}Enabled - $w5udsched - UP ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname5${CClear}" - else - echo -e "${InvGreen} ${CClear} ${CWhite}5.0GHz ${CDkGray}[ ${CWhite}Enabled - $w5udsched - DOWN ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname5${CClear}" - fi - preparebar 79 "|" - progressbar $oldw5rxmbrate $MaxSpeed5GhzNow " Avg 5G1 RX" "Mbps" "Standard" $oldw5rxmbratedisplay $MaxSpeed5GhzNow - echo "" - preparebar 79 "|" - progressbar $oldw5txmbrate $MaxSpeed5GhzNow " Avg 5G1 TX" "Mbps" "Standard" $oldw5txmbratedisplay $MaxSpeed5GhzNow - echo "" - preparebar 79 "|" - converttemps $oldw5temp - progressbar $currenttemp $currentrange " 5G-1 Temp " $TempUnits "Standard" $currenttemp $currentrange - else - echo "" - echo "" - echo -e "${InvRed} ${CClear}${CWhite} 5.0GHz ${CDkGray}[ ${CRed}Disabled ${CDkGray}]${CClear}" - fi - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then - if [ "$MaxSpeed52GhzNow" != "0" ]; then - echo "" - echo "" - if [ "$w52updown" == "UP" ]; then - echo -e "${InvGreen} ${CClear} ${CWhite}5.0GHz (2) ${CDkGray}[ ${CWhite}Enabled - $w52udsched - UP ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname52${CClear}" - else - echo -e "${InvGreen} ${CClear} ${CWhite}5.0GHz (2) ${CDkGray}[ ${CWhite}Enabled - $w52udsched - DOWN ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname52${CClear}" - fi - preparebar 79 "|" - progressbar $oldw52rxmbrate $MaxSpeed5GhzNow " Avg 5G2 RX" "Mbps" "Standard" $oldw52rxmbratedisplay $MaxSpeed5GhzNow - echo "" - preparebar 79 "|" - progressbar $oldw52txmbrate $MaxSpeed5GhzNow " Avg 5G2 TX" "Mbps" "Standard" $oldw52txmbratedisplay $MaxSpeed5GhzNow - echo "" - preparebar 79 "|" - converttemps $oldw52temp - progressbar $currenttemp $currentrange " 5G-2 Temp " $TempUnits "Standard" $currenttemp $currentrange - else - echo "" - echo "" - echo -e "${InvRed} ${CClear}${CWhite} 5.0GHz (2) ${CDkGray}[ ${CRed}Disabled ${CDkGray}]${CClear}" - fi - fi - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then - if [ "$MaxSpeed6GhzNow" != "0" ]; then - echo "" - echo "" - if [ "$w6updown" == "UP" ]; then - echo -e "${InvGreen} ${CClear} ${CWhite}6.0GHz ${CDkGray}[ ${CWhite}Enabled - $w6udsched - UP ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname6${CClear}" - else - echo -e "${InvGreen} ${CClear} ${CWhite}6.0GHz ${CDkGray}[ ${CWhite}Enabled - $w6udsched - DOWN ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname6${CClear}" - fi - preparebar 79 "|" - progressbar $oldw6rxmbrate $MaxSpeed6GhzNow " Avg 60G RX" "Mbps" "Standard" $oldw6rxmbratedisplay $MaxSpeed6GhzNow - echo "" - preparebar 79 "|" - progressbar $oldw6txmbrate $MaxSpeed6GhzNow " Avg 60G TX" "Mbps" "Standard" $oldw6txmbratedisplay $MaxSpeed6GhzNow - echo "" - preparebar 79 "|" - converttemps $oldw6temp - progressbar $currenttemp $currentrange " 6.0G Temp " $TempUnits "Standard" $currenttemp $currentrange - else - echo "" - echo "" - echo -e "${InvRed} ${CClear}${CWhite} 6.0GHz ${CDkGray}[ ${CRed}Disabled ${CDkGray}]${CClear}" - fi - fi - if [ "$FourBandCustom56624" == "True" ]; then - if [ "$MaxSpeed62GhzNow" != "0" ]; then - echo "" - echo "" - if [ "$w62updown" == "UP" ]; then - echo -e "${InvGreen} ${CClear} ${CWhite}6.0GHz (2) ${CDkGray}[ ${CWhite}Enabled - $w62udsched - UP ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname62${CClear}" - else - echo -e "${InvGreen} ${CClear} ${CWhite}6.0GHz (2) ${CDkGray}[ ${CWhite}Enabled - $w62udsched - DOWN ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname62${CClear}" - fi - preparebar 79 "|" - progressbar $oldw62rxmbrate $MaxSpeed62GhzNow " Avg 6G2 RX" "Mbps" "Standard" $oldw62rxmbratedisplay $MaxSpeed62GhzNow - echo "" - preparebar 79 "|" - progressbar $oldw62txmbrate $MaxSpeed62GhzNow " Avg 6G2 TX" "Mbps" "Standard" $oldw62txmbratedisplay $MaxSpeed62GhzNow - echo "" - preparebar 79 "|" - converttemps $oldw62temp - progressbar $currenttemp $currentrange " 6G-2 Temp " $TempUnits "Standard" $currenttemp $currentrange - else - echo "" - echo "" - echo -e "${InvRed} ${CClear}${CWhite} 6.0GHz (2) ${CDkGray}[ ${CRed}Disabled ${CDkGray}]${CClear}" - fi - fi -} - -# ------------------------------------------------------------------------------------------------------------------------- - -# This function displays the stats UI for page 4 -DisplayPage4() -{ - clear - if [ "$UpdateNotify" != "0" ]; then - echo -e "$UpdateNotify${CClear}" - fi - showheader - echo "" - echo -e "${InvDkGray}${CWhite} Speedtest ${CClear}" - - if [ "$QueueVPNSlot1" = "1" ]; then - DisplaySpdtst 1 - elif [ "$QueueVPNSlot2" = "1" ]; then - DisplaySpdtst 2 - elif [ "$QueueVPNSlot3" = "1" ]; then - DisplaySpdtst 3 - elif [ "$QueueVPNSlot4" = "1" ]; then - DisplaySpdtst 4 - elif [ "$QueueVPNSlot5" = "1" ]; then - DisplaySpdtst 5 - elif [ "$QueueWGSlot1" = "1" ]; then - DisplaySpdtst 6 - elif [ "$QueueWGSlot2" = "1" ]; then - DisplaySpdtst 7 - elif [ "$QueueWGSlot3" = "1" ]; then - DisplaySpdtst 8 - elif [ "$QueueWGSlot4" = "1" ]; then - DisplaySpdtst 9 - elif [ "$QueueWGSlot5" = "1" ]; then - DisplaySpdtst 0 - else - DisplaySpdtst - fi -} - -# ------------------------------------------------------------------------------------------------------------------------- - -# This function displays speedtest results and runs new speedtest -# $1 = VPN Slot - -DisplaySpdtst() -{ - if [ "$Speedtst" = "0" ] || [ ! -f $OOKLAPATH ]; then - echo -e "${InvGreen} ${CClear}" - echo -e "${InvRed} ${CClear} ${CRed}[Ookla Speedtest is not installed/configured]${CClear}" - sleep 3 - return - fi - - # Check to see if previous results are available to display - if [ -f "$SPDRESPATH" ]; then - source "$SPDRESPATH" - else - SpdDate="No previous results found" - SpdServer="Press 'I' to Initiate a Speedtest" - SpdLatency=0 - SpdJitter=0 - SpdPacketLoss=0 - SpdDownload=0 - SpdUpload=0 - fi - - echo -e "${InvGreen} ${CClear}" - - if [ "$QueueSpdTest" = "1" ] - then - #run speedtest and save Results - printf "\r${InvGreen} ${CClear} ${CGreen}[Initializing WAN Speedtest]" - #printf "${CGreen}\r[Initializing WAN Speedtest]" - if [ $spdtestsvrID == "0" ]; then - speed="$(/jffs/addons/rtrmon.d/speedtest --format=csv --interface=$WANIFNAME --accept-license --accept-gdpr 2>&1)" - else - speed="$(/jffs/addons/rtrmon.d/speedtest --format=csv --interface=$WANIFNAME --server-id=$spdtestsvrID --accept-license --accept-gdpr 2>&1)" - fi - SpdDate=$(date) - SpdServer=$(echo $speed | awk -F '","' 'NR==1 {print $1}' | sed -e 's/^"//' -e 's/"$//' -e 's/[^a-zA-Z0-9 -]//g') - SpdLatency=$(echo $speed | awk -F '","' 'NR==1 {print $3}' | sed -e 's/^"//' -e 's/"$//') - SpdLatencyLo=$(echo $speed | awk -F '","' 'NR==1 {print $20}' | sed -e 's/^"//' -e 's/"$//') - SpdLatencyHi=$(echo $speed | awk -F '","' 'NR==1 {print $21}' | sed -e 's/^"//' -e 's/"$//') - SpdJitter=$(echo $speed | awk -F '","' 'NR==1 {print $4}' | sed -e 's/^"//' -e 's/"$//') - SpdPacketLoss=$(echo $speed | awk -F '","' 'NR==1 {print $5}' | sed -e 's/^"//' -e 's/"$//') - SpdDownload=$(echo $speed | awk -F '","' 'NR==1 {print $6}' | sed -e 's/^"//' -e 's/"$//') - SpdUpload=$(echo $speed | awk -F '","' 'NR==1 {print $7}' | sed -e 's/^"//' -e 's/"$//') - SpdDLLatency=$(echo $speed | awk -F '","' 'NR==1 {print $12}' | sed -e 's/^"//' -e 's/"$//') - SpdDLLatencyJt=$(echo $speed | awk -F '","' 'NR==1 {print $13}' | sed -e 's/^"//' -e 's/"$//') - SpdDLLatencyLo=$(echo $speed | awk -F '","' 'NR==1 {print $14}' | sed -e 's/^"//' -e 's/"$//') - SpdDLLatencyHi=$(echo $speed | awk -F '","' 'NR==1 {print $15}' | sed -e 's/^"//' -e 's/"$//') - SpdULLatency=$(echo $speed | awk -F '","' 'NR==1 {print $16}' | sed -e 's/^"//' -e 's/"$//') - SpdULLatencyJt=$(echo $speed | awk -F '","' 'NR==1 {print $17}' | sed -e 's/^"//' -e 's/"$//') - SpdULLatencyLo=$(echo $speed | awk -F '","' 'NR==1 {print $18}' | sed -e 's/^"//' -e 's/"$//') - SpdULLatencyHi=$(echo $speed | awk -F '","' 'NR==1 {print $19}' | sed -e 's/^"//' -e 's/"$//') - - if [ $SpdDownload -eq 0 ]; then SpdDownload=1; fi - if [ $SpdUpload -eq 0 ]; then SpdUpload=1; fi - - SpdDownloadLog=$(awk -v down=$SpdDownload -v mb=125000 'BEGIN{printf "%.0f\n", down/mb}') - SpdUploadLog=$(awk -v up=$SpdUpload -v mb=125000 'BEGIN{printf "%.0f\n", up/mb}') - SpdInterface=$WANIFNAME - - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - New Speedtest Results -- Down:$SpdDownloadLog Mbps | Up:$SpdUploadLog Mbps | Latency:$SpdLatency ms | Jitter:$SpdJitter ms | PacketLoss:$SpdPacketLoss %" >> $LOGFILE - - { echo 'SpdDate="'"$SpdDate"'"' - echo 'SpdServer="'"$SpdServer"'"' - echo 'SpdInterface="'"$SpdInterface"'"' - echo 'SpdLatency='$SpdLatency - echo 'SpdLatencyLo='$SpdLatencyLo - echo 'SpdLatencyHi='$SpdLatencyHi - echo 'SpdJitter='$SpdJitter - echo 'SpdPacketLoss='$SpdPacketLoss - echo 'SpdDownload='$SpdDownload - echo 'SpdUpload='$SpdUpload - echo 'SpdDLLatency='$SpdDLLatency - echo 'SpdDLLatencyJt='$SpdDLLatencyJt - echo 'SpdDLLatencyLo='$SpdDLLatencyLo - echo 'SpdDLLatencyHi='$SpdDLLatencyHi - echo 'SpdULLatency='$SpdULLatency - echo 'SpdULLatencyJt='$SpdULLatencyJt - echo 'SpdULLatencyLo='$SpdULLatencyLo - echo 'SpdULLatencyHi='$SpdULLatencyHi - } > "$SPDRESPATH" - printf "${CGreen}\r" - QueueSpdTest=0 - fi - - if [ "$1" = "1" ] || [ "$1" = "2" ] || [ "$1" = "3" ] || [ "$1" = "4" ] || [ "$1" = "5" ] - then - #run VPN speedtest and save Results - selectedvpnslot="vpn${1}on" - eval selectedvpnslot="\$${selectedvpnslot}" - if [ "$selectedvpnslot" = "True" ] && [ "$VPNSite2Site" = "0" ] - then - printf "\r${InvGreen} ${CClear} ${CGreen}[Initializing VPN$1 Speedtest]" - if [ $spdtestsvrID == "0" ]; then - speed="$(/jffs/addons/rtrmon.d/speedtest --format=csv --interface=tun1$1 --accept-license --accept-gdpr 2>&1)" - else - speed="$(/jffs/addons/rtrmon.d/speedtest --format=csv --interface=tun1$1 --server-id=$spdtestsvrID --accept-license --accept-gdpr 2>&1)" - fi - SpdDate=$(date) - SpdServer=$(echo $speed | awk -F '","' 'NR==1 {print $1}' | sed -e 's/^"//' -e 's/"$//' -e 's/[^a-zA-Z0-9 -]//g') - SpdLatency=$(echo $speed | awk -F '","' 'NR==1 {print $3}' | sed -e 's/^"//' -e 's/"$//') - SpdLatencyLo=$(echo $speed | awk -F '","' 'NR==1 {print $20}' | sed -e 's/^"//' -e 's/"$//') - SpdLatencyHi=$(echo $speed | awk -F '","' 'NR==1 {print $21}' | sed -e 's/^"//' -e 's/"$//') - SpdJitter=$(echo $speed | awk -F '","' 'NR==1 {print $4}' | sed -e 's/^"//' -e 's/"$//') - SpdPacketLoss=$(echo $speed | awk -F '","' 'NR==1 {print $5}' | sed -e 's/^"//' -e 's/"$//') - SpdDownload=$(echo $speed | awk -F '","' 'NR==1 {print $6}' | sed -e 's/^"//' -e 's/"$//') - SpdUpload=$(echo $speed | awk -F '","' 'NR==1 {print $7}' | sed -e 's/^"//' -e 's/"$//') - SpdDLLatency=$(echo $speed | awk -F '","' 'NR==1 {print $12}' | sed -e 's/^"//' -e 's/"$//') - SpdDLLatencyJt=$(echo $speed | awk -F '","' 'NR==1 {print $13}' | sed -e 's/^"//' -e 's/"$//') - SpdDLLatencyLo=$(echo $speed | awk -F '","' 'NR==1 {print $14}' | sed -e 's/^"//' -e 's/"$//') - SpdDLLatencyHi=$(echo $speed | awk -F '","' 'NR==1 {print $15}' | sed -e 's/^"//' -e 's/"$//') - SpdULLatency=$(echo $speed | awk -F '","' 'NR==1 {print $16}' | sed -e 's/^"//' -e 's/"$//') - SpdULLatencyJt=$(echo $speed | awk -F '","' 'NR==1 {print $17}' | sed -e 's/^"//' -e 's/"$//') - SpdULLatencyLo=$(echo $speed | awk -F '","' 'NR==1 {print $18}' | sed -e 's/^"//' -e 's/"$//') - SpdULLatencyHi=$(echo $speed | awk -F '","' 'NR==1 {print $19}' | sed -e 's/^"//' -e 's/"$//') - - if [ $SpdDownload -eq 0 ]; then SpdDownload=1; fi - if [ $SpdUpload -eq 0 ]; then SpdUpload=1; fi - - SpdDownloadLog=$(awk -v down=$SpdDownload -v mb=125000 'BEGIN{printf "%.0f\n", down/mb}') - SpdUploadLog=$(awk -v up=$SpdUpload -v mb=125000 'BEGIN{printf "%.0f\n", up/mb}') - SpdInterface="tun1$1" - - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - New VPN$1 Speedtest Results -- Down:$SpdDownloadLog Mbps | Up:$SpdUploadLog Mbps | Latency:$SpdLatency ms | Jitter:$SpdJitter ms | PacketLoss:$SpdPacketLoss %" >> $LOGFILE - - { echo 'SpdDate="'"$SpdDate"'"' - echo 'SpdServer="'"$SpdServer"'"' - echo 'SpdInterface="'"$SpdInterface"'"' - echo 'SpdLatency='$SpdLatency - echo 'SpdLatencyLo='$SpdLatencyLo - echo 'SpdLatencyHi='$SpdLatencyHi - echo 'SpdJitter='$SpdJitter - echo 'SpdPacketLoss='$SpdPacketLoss - echo 'SpdDownload='$SpdDownload - echo 'SpdUpload='$SpdUpload - echo 'SpdDLLatency='$SpdDLLatency - echo 'SpdDLLatencyJt='$SpdDLLatencyJt - echo 'SpdDLLatencyLo='$SpdDLLatencyLo - echo 'SpdDLLatencyHi='$SpdDLLatencyHi - echo 'SpdULLatency='$SpdULLatency - echo 'SpdULLatencyJt='$SpdULLatencyJt - echo 'SpdULLatencyLo='$SpdULLatencyLo - echo 'SpdULLatencyHi='$SpdULLatencyHi - } > $SPDRESPATH - printf "\r${CClear}" - QueueVPNSlot1=0 - QueueVPNSlot2=0 - QueueVPNSlot3=0 - QueueVPNSlot4=0 - QueueVPNSlot5=0 - else - printf "\r${InvRed} ${CClear}${CRed} [No valid VPN tunnel detected to run Speedtest on]${CClear}" - sleep 3 - printf "\r${CClear} " - QueueVPNSlot1=0 - QueueVPNSlot2=0 - QueueVPNSlot3=0 - QueueVPNSlot4=0 - QueueVPNSlot5=0 - fi - fi - - if [ "$1" = "0" ] || [ "$1" = "6" ] || [ "$1" = "7" ] || [ "$1" = "8" ] || [ "$1" = "9" ] - then - if [ $1 -eq 6 ]; then selectedslotnum=1 - elif [ $1 -eq 7 ]; then selectedslotnum=2 - elif [ $1 -eq 8 ]; then selectedslotnum=3 - elif [ $1 -eq 9 ]; then selectedslotnum=4 - elif [ $1 -eq 0 ]; then selectedslotnum=5 - fi - #run WG speedtest and save Results - selectedwgslot="wg${selectedslotnum}on" - eval selectedwgslot="\$${selectedwgslot}" - if [ "$selectedwgslot" = "True" ] && [ "$VPNSite2Site" = "0" ] - then - - SPDWGTUN="wgc$selectedslotnum" - SPDNVRAMWGSLOTADDR=$($timeoutcmd$timeoutsec nvram get "$SPDWGTUN"_addr | cut -d '/' -f1) - - # Added based on suggestion from @ZebMcKayhan - ip rule add from $SPDNVRAMWGSLOTADDR lookup $SPDWGTUN prio 10 >/dev/null 2>&1 - ip -6 rule add from all oif $SPDWGTUN lookup $SPDWGTUN prio 10 >/dev/null 2>&1 #Mod to handle IPv6 - - printf "\r${InvGreen} ${CClear} ${CGreen}[Initializing WG${selectedslotnum} Speedtest]" - - if [ $spdtestsvrID == "0" ]; then - speed="$(/jffs/addons/rtrmon.d/speedtest --format=csv --interface=wgc${selectedslotnum} --accept-license --accept-gdpr 2>&1)" - else - speed="$(/jffs/addons/rtrmon.d/speedtest --format=csv --interface=wgc${selectedslotnum} --server-id=$spdtestsvrID --accept-license --accept-gdpr 2>&1)" - fi - - # Added based on suggestion from @ZebMcKayhan - ip rule del prio 10 >/dev/null 2>&1 - ip -6 rule del prio 10 >/dev/null 2>&1 - - # Clean up any garbage data per @ZebMcKayhan - speed=$(echo $speed | sed 's/^[^"]*//') - - SpdDate=$(date) - SpdServer=$(echo $speed | awk -F '","' 'NR==1 {print $1}' | sed -e 's/^"//' -e 's/"$//' -e 's/[^a-zA-Z0-9 -]//g') - SpdLatency=$(echo $speed | awk -F '","' 'NR==1 {print $3}' | sed -e 's/^"//' -e 's/"$//') - SpdLatencyLo=$(echo $speed | awk -F '","' 'NR==1 {print $20}' | sed -e 's/^"//' -e 's/"$//') - SpdLatencyHi=$(echo $speed | awk -F '","' 'NR==1 {print $21}' | sed -e 's/^"//' -e 's/"$//') - SpdJitter=$(echo $speed | awk -F '","' 'NR==1 {print $4}' | sed -e 's/^"//' -e 's/"$//') - SpdPacketLoss=$(echo $speed | awk -F '","' 'NR==1 {print $5}' | sed -e 's/^"//' -e 's/"$//') - SpdDownload=$(echo $speed | awk -F '","' 'NR==1 {print $6}' | sed -e 's/^"//' -e 's/"$//') - SpdUpload=$(echo $speed | awk -F '","' 'NR==1 {print $7}' | sed -e 's/^"//' -e 's/"$//') - SpdDLLatency=$(echo $speed | awk -F '","' 'NR==1 {print $12}' | sed -e 's/^"//' -e 's/"$//') - SpdDLLatencyJt=$(echo $speed | awk -F '","' 'NR==1 {print $13}' | sed -e 's/^"//' -e 's/"$//') - SpdDLLatencyLo=$(echo $speed | awk -F '","' 'NR==1 {print $14}' | sed -e 's/^"//' -e 's/"$//') - SpdDLLatencyHi=$(echo $speed | awk -F '","' 'NR==1 {print $15}' | sed -e 's/^"//' -e 's/"$//') - SpdULLatency=$(echo $speed | awk -F '","' 'NR==1 {print $16}' | sed -e 's/^"//' -e 's/"$//') - SpdULLatencyJt=$(echo $speed | awk -F '","' 'NR==1 {print $17}' | sed -e 's/^"//' -e 's/"$//') - SpdULLatencyLo=$(echo $speed | awk -F '","' 'NR==1 {print $18}' | sed -e 's/^"//' -e 's/"$//') - SpdULLatencyHi=$(echo $speed | awk -F '","' 'NR==1 {print $19}' | sed -e 's/^"//' -e 's/"$//') - - if [ $SpdDownload -eq 0 ]; then SpdDownload=1; fi - if [ $SpdUpload -eq 0 ]; then SpdUpload=1; fi - - SpdDownloadLog=$(awk -v down=$SpdDownload -v mb=125000 'BEGIN{printf "%.0f\n", down/mb}') - SpdUploadLog=$(awk -v up=$SpdUpload -v mb=125000 'BEGIN{printf "%.0f\n", up/mb}') - SpdInterface="wgc${selectedslotnum}" - - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - New WG${selectedslotnum} Speedtest Results -- Down:$SpdDownloadLog Mbps | Up:$SpdUploadLog Mbps | Latency:$SpdLatency ms | Jitter:$SpdJitter ms | PacketLoss:$SpdPacketLoss %" >> $LOGFILE - - { echo 'SpdDate="'"$SpdDate"'"' - echo 'SpdServer="'"$SpdServer"'"' - echo 'SpdInterface="'"$SpdInterface"'"' - echo 'SpdLatency='$SpdLatency - echo 'SpdLatencyLo='$SpdLatencyLo - echo 'SpdLatencyHi='$SpdLatencyHi - echo 'SpdJitter='$SpdJitter - echo 'SpdPacketLoss='$SpdPacketLoss - echo 'SpdDownload='$SpdDownload - echo 'SpdUpload='$SpdUpload - echo 'SpdDLLatency='$SpdDLLatency - echo 'SpdDLLatencyJt='$SpdDLLatencyJt - echo 'SpdDLLatencyLo='$SpdDLLatencyLo - echo 'SpdDLLatencyHi='$SpdDLLatencyHi - echo 'SpdULLatency='$SpdULLatency - echo 'SpdULLatencyJt='$SpdULLatencyJt - echo 'SpdULLatencyLo='$SpdULLatencyLo - echo 'SpdULLatencyHi='$SpdULLatencyHi - } > $SPDRESPATH - printf "\r${CClear}" - QueueWGSlot1=0 - QueueWGSlot2=0 - QueueWGSlot3=0 - QueueWGSlot4=0 - QueueWGSlot5=0 - else - printf "\r${InvRed} ${CClear}${CRed} [No valid WG tunnel detected to run Speedtest on]${CClear}" - sleep 3 - printf "\r${CClear} " - QueueWGSlot1=0 - QueueWGSlot2=0 - QueueWGSlot3=0 - QueueWGSlot4=0 - QueueWGSlot5=0 - fi - fi - - # Display previous results - if [ $SpdDownload -eq 0 ] || [ -z $SpdDownload ]; then SpdDownload=1; fi - if [ $SpdUpload -eq 0 ] || [ -z $SpdUpload ]; then SpdUpload=1; fi - - SpdDownload=$(awk -v down=$SpdDownload -v mb=125000 'BEGIN{printf "%.0f\n", down/mb}') - SpdUpload=$(awk -v up=$SpdUpload -v mb=125000 'BEGIN{printf "%.0f\n", up/mb}') - - if [ "$ScreenshotMode" == "1" ]; then - SpdServer="Starlink Satellite Transceiver #488028" - fi - - if { [ "$vpn1on" = "True" ] || [ "$vpn2on" = "True" ] || [ "$vpn3on" = "True" ] || [ "$vpn4on" = "True" ] || [ "$vpn5on" = "True" ]; } && { [ "$wg1on" = "True" ] || [ "$wg2on" = "True" ] || [ "$wg3on" = "True" ] || [ "$wg4on" = "True" ] || [ "$wg5on" = "True" ]; }; then - printf "\r${InvGreen} ${CClear} ${CGreen}(I)${CWhite}nitiate WAN Speedtest on: ${CGreen}$WANIFNAME ${CWhite}| VPN 1:${CGreen}(1) ${CWhite}2:${CGreen}(2) ${CWhite}3:${CGreen}(3) ${CWhite}4:${CGreen}(4) ${CWhite}5:${CGreen}(5) ${CWhite} | WG 1:${CGreen}(6) ${CWhite}2:${CGreen}(7) ${CWhite}3:${CGreen}(8) ${CWhite}4:${CGreen}(9) ${CWhite}5:${CGreen}(0)${CClear}" - elif [ "$vpn1on" = "True" ] || [ "$vpn2on" = "True" ] || [ "$vpn3on" = "True" ] || [ "$vpn4on" = "True" ] || [ "$vpn5on" = "True" ]; then - printf "\r${InvGreen} ${CClear} ${CGreen}(I)${CWhite}nitiate WAN Speedtest on: ${CGreen}$WANIFNAME ${CWhite}| VPN 1:${CGreen}(1) ${CWhite}2:${CGreen}(2) ${CWhite}3:${CGreen}(3) ${CWhite}4:${CGreen}(4) ${CWhite}5:${CGreen}(5) ${CWhite} | ${CDkGray}WG 1:(6) 2:(7) 3:(8) 4:(9) 5:(0)${CClear}" - elif [ "$wg1on" = "True" ] || [ "$wg2on" = "True" ] || [ "$wg3on" = "True" ] || [ "$wg4on" = "True" ] || [ "$wg5on" = "True" ]; then - printf "\r${InvGreen} ${CClear} ${CGreen}(I)${CWhite}nitiate WAN Speedtest on: ${CGreen}$WANIFNAME ${CWhite}| ${CDkGray}VPN 1:(1) 2:(2) 3:(3) 4:(4) 5:(5) ${CWhite} | WG 1:${CGreen}(6) ${CWhite}2:${CGreen}(7) ${CWhite}3:${CGreen}(8) ${CWhite}4:${CGreen}(9) ${CWhite}5:${CGreen}(0)${CClear}" - else - printf "\r${InvGreen} ${CClear} ${CGreen}(I)${CWhite}nitiate WAN Speedtest${CClear} " - fi - - echo "" - echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" - echo "" - echo -e "${InvGreen} ${CClear} ${CWhite}Test Date ${CDkGray}[ ${CGreen}$SpdDate${CClear}" - echo -e "${InvGreen} ${CClear} ${CWhite}Server ${CDkGray}[ ${CGreen}$SpdServer${CClear}" - echo -e "${InvGreen} ${CClear} ${CWhite}Interface ${CDkGray}[ ${CGreen}$SpdInterface${CClear}" - echo "" - echo -e "${InvGreen} ${CClear} ${CWhite}Idle Latency ${CDkGray}[ ${CGreen}$SpdLatency (ms)${CWhite} | Latency Low: ${CGreen}$SpdLatencyLo (ms) ${CWhite}| High: ${CGreen}$SpdLatencyHi (ms)${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} ${CWhite}Idle Jitter ${CDkGray}[ ${CGreen}$SpdJitter (ms)${CClear}" - echo -e "${InvGreen} ${CClear} ${CWhite}PacketLoss ${CDkGray}[ ${CGreen}$SpdPacketLoss (%)${CClear}" - echo "" - echo -e "${InvGreen} ${CClear} ${CWhite}Download ${CDkGray}[ ${CGreen}$SpdDownload (Mbps)${CWhite} | Jitter: ${CGreen}$SpdDLLatencyJt (ms)${CClear}" - echo -e "${InvGreen} ${CClear} ${CDkGray} [ ${CWhite}Latency: ${CGreen}$SpdDLLatency (ms)${CWhite} | Latency Low: ${CGreen}$SpdDLLatencyLo (ms) ${CWhite}| High: ${CGreen}$SpdDLLatencyHi (ms)${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} ${CCyan}Upload ${CDkGray}[ ${CGreen}$SpdUpload (Mbps)${CWhite} | Jitter: ${CGreen}$SpdULLatencyJt (ms)${CClear}" - echo -e "${InvGreen} ${CClear} ${CDkGray} [ ${CWhite}Latency: ${CGreen}$SpdULLatency (ms)${CWhite} | Latency Low: ${CGreen}$SpdULLatencyLo (ms) ${CWhite}| High: ${CGreen}$SpdULLatencyHi (ms)${CClear}" - echo "" - preparebar 79 "|" - progressbar $SpdDownload $MaxSpeedInet " DL vs WAN " "Mbps" "Reverse" $SpdDownload $MaxSpeedInet - echo "" - preparebar 79 "|" - progressbar $SpdUpload $MaxSpeedInetUL " UL vs WAN " "Mbps" "Reverse" $SpdUpload $MaxSpeedInetUL -} - -# ------------------------------------------------------------------------------------------------------------------------- - -# This function displays the stats UI for page 5 which includes network diagnostics and open port scanning -DisplayPage5() -{ - local ALIVE - local YEAR - local NW_STATE - local RES_STATE - local HOST_STATE - local CURL_STATE - local SPIDER_STATE - local SSL_STATE - #oldwan0ip="123.45.67.89" - - # Check to see if previous results are available to display - if [ -f "$DIAGRESPATH" ]; then - source "$DIAGRESPATH" - else - Lastruntime="No previous results found" - LocalClockTest="Failed" - NetworkConnTest="Failed" - NetworkResTest="Failed" - DigFuncTest="Failed" - CurlFuncTest="Failed" - SpiderFuncTest="Failed" - SSLHandshakeTest="Failed" - fi - - clear - if [ "$UpdateNotify" != "0" ]; then - echo -e "$UpdateNotify${CClear}" - fi - showheader - echo "" - echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} Network Diagnostics ${CClear}" - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear} ${CWhite}Run ${CGreen}(D)${CWhite}iagnostics | Last Run Date/Time: ${CGreen}$Lastruntime" - echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" - echo "" - - if [ "$QueueNetworkDiag" = "1" ] - then - #run network diags and save Results - printf "${InvYellow} ${CClear} ${CWhite}Local Clock Test... ${CYellow}[Checking] ${CDkGray}| date > 1970${CClear}" - YEAR="$(/bin/date +"%Y")" - sleep 1 - if [ "$YEAR" -gt 1970 ]; then - printf "\r${InvGreen} ${CClear} ${CWhite}Local Clock Test... ${CGreen}[Passed] ${CDkGray}| date > 1970${CClear}" - LocalClockTest="Passed" - else - printf "\r${InvRed} ${CClear} ${CWhite}Local Clock Test... ${CRed}[Failed] ${CDkGray}| date > 1970${CClear}" - LocalClockTest="Failed" - fi - echo "" - printf "${InvYellow} ${CClear} ${CWhite}Network Connectivity Test... ${CYellow}[Checking] ${CDkGray}| ping 1.1.1.1 -c1 -W2${CClear}" - NW_STATE="$(ping 1.1.1.1 -c1 -W2 >/dev/null 2>&1; echo $?)" - sleep 1 - if [ "$NW_STATE" = "0" ]; then - printf "\r${InvGreen} ${CClear} ${CWhite}Network Connectivity Test... ${CGreen}[Passed] ${CDkGray}| ping 1.1.1.1 -c1 -W2${CClear}" - NetworkConnTest="Passed" - else - printf "\r${InvRed} ${CClear} ${CWhite}Network Connectivity Test... ${CRed}[Failed] ${CDkGray}| ping 1.1.1.1 -c1 -W2${CClear}" - NetworkConnTest="Failed" - fi - echo "" - - if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then - printf "${InvYellow} ${CClear} ${CWhite}Network Resolution Test... ${CYellow}[Checking] ${CDkGray}| nslookup google.com 127.0.0.1${CClear}" - RES_STATE="$(nslookup google.com 127.0.0.1 >/dev/null 2>&1; echo $?)" - sleep 1 - if [ "$RES_STATE" = "0" ]; then - printf "\r${InvGreen} ${CClear} ${CWhite}Network Resolution Test... ${CGreen}[Passed] ${CDkGray}| nslookup google.com 127.0.0.1${CClear}" - NetworkResTest="Passed" - else - printf "\r${InvRed} ${CClear} ${CWhite}Network Resolution Test... ${CRed}[Failed] ${CDkGray}| nslookup google.com 127.0.0.1${CClear}" - NetworkResTest="Failed" - fi - echo "" - else - printf "${InvYellow} ${CClear} ${CWhite}Network Resolution Test... ${CYellow}[Checking] ${CDkGray}| nslookup google.com${CClear}" - RES_STATE="$(nslookup google.com >/dev/null 2>&1; echo $?)" - sleep 1 - if [ "$RES_STATE" = "0" ]; then - printf "\r${InvGreen} ${CClear} ${CWhite}Network Resolution Test... ${CGreen}[Passed] ${CDkGray}| nslookup google.com${CClear}" - NetworkResTest="Passed" - else - printf "\r${InvRed} ${CClear} ${CWhite}Network Resolution Test... ${CRed}[Failed] ${CDkGray}| nslookup google.com${CClear}" - NetworkResTest="Failed" - fi - echo "" - fi - - printf "${InvYellow} ${CClear} ${CWhite}Dig Functionality Test... ${CYellow}[Checking] ${CDkGray}| dig google.com${CClear}" - DIG_STATE="$(dig google.com >/dev/null 2>&1; echo $?)" - sleep 1 - if [ "$DIG_STATE" = "0" ]; then - printf "\r${InvGreen} ${CClear} ${CWhite}Dig Functionality Test... ${CGreen}[Passed] ${CDkGray}| dig google.com${CClear}" - DigFuncTest="Passed" - else - printf "\r${InvRed} ${CClear} ${CWhite}Dig Functionality Test... ${CRed}[Failed] ${CDkGray}| dig google.com${CClear}" - DigFuncTest="Failed" - fi - echo "" - - printf "${InvYellow} ${CClear} ${CWhite}Curl Functionality Test... ${CYellow}[Checking] ${CDkGray}| curl -Is http://www.google.com | head -n 1${CClear}" - CURL_STATE="$(curl -Is http://www.google.com | head -n 1 >/dev/null 2>&1; echo $?)" - sleep 1 - if [ "$CURL_STATE" = "0" ]; then - printf "\r${InvGreen} ${CClear} ${CWhite}Curl Functionality Test... ${CGreen}[Passed] ${CDkGray}| curl -Is http://www.google.com | head -n 1${CClear}" - CurlFuncTest="Passed" - else - printf "\r${InvRed} ${CClear} ${CWhite}Curl Functionality Test... ${CRed}[Failed] ${CDkGray}| curl -Is http://www.google.com | head -n 1${CClear}" - CurlFuncTest="Failed" - fi - echo "" - - printf "${InvYellow} ${CClear} ${CWhite}Spider Functionality Test... ${CYellow}[Checking] ${CDkGray}| wget -q --spider http://google.com${CClear}" - SPIDER_STATE="$(wget -q --spider http://google.com >/dev/null 2>&1; echo $?)" - sleep 1 - if [ "$SPIDER_STATE" = "0" ]; then - printf "\r${InvGreen} ${CClear} ${CWhite}Spider Functionality Test... ${CGreen}[Passed] ${CDkGray}| wget -q --spider http://google.com${CClear}" - SpiderFuncTest="Passed" - else - printf "\r${InvRed} ${CClear} ${CWhite}Spider Functionality Test... ${CRed}[Failed] ${CDkGray}| wget -q --spider http://google.com${CClear}" - SpiderFuncTest="Failed" - fi - echo "" - - printf "${InvYellow} ${CClear} ${CWhite}SSL Handshake Test... ${CYellow}[Checking] ${CDkGray}| nc -w3 8.8.8.8 443 && echo | openssl s_client -connect 8.8.8.8:443>${CClear}" - SSL_STATE="$(nc -w3 8.8.8.8 443 >/dev/null 2>&1 && echo | openssl s_client -connect 8.8.8.8:443 >/dev/null 2>&1 | awk 'handshake && $1 == "Verification" { if ($2=="OK") exit; exit 1 } $1 $2 == "SSLhandshake" { handshake = 1 }' >/dev/null 2>&1; echo $?)" - sleep 1 - if [ "$SSL_STATE" = "0" ]; then - printf "\r${InvGreen} ${CClear} ${CWhite}SSL Handshake Test... ${CGreen}[Passed] ${CDkGray}| nc -w3 8.8.8.8 443 && echo | openssl s_client -connect 8.8.8.8:443>${CClear}" - SSLHandshakeTest="Passed" - else - printf "\r${InvRed} ${CClear} ${CWhite}SSL Handshake Test... ${CRed}[Failed] ${CDkGray}| nc -w3 8.8.8.8 443 && echo | openssl s_client -connect 8.8.8.8:443>${CClear}" - SSLHandshakeTest="Failed" - fi - echo "" - echo "" - echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} NMAP Port Scan Results ${CClear}" - - if [ "$PSView" == "TCP" ]; then - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear}${CWhite} Show Open ${InvDkGray} ${CGreen}(T)${CWhite}CP ${CClear}${CWhite} Ports | Show Open ${CGreen}(U)${CWhite}DP Ports${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" - echo "" - if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then - echo -e "${InvGreen} ${CClear} ${CWhite}WAN0 IP: ${CGreen}$oldwan0ip${CClear}" - WANnmap=$(nmap $oldwan0ip | grep "open") - if [ -z "$WANnmap" ]; then echo "None"; else nmap $oldwan0ip | grep "open"; fi - echo "" - fi - echo -e "${InvGreen} ${CClear} ${CWhite}BR0 IP: ${CGreen}$oldlanip${CClear}" - LANnmap=$(nmap $oldlanip | grep "open") - if [ -z "$LANnmap" ]; then echo "None"; else nmap $oldlanip | grep "open"; fi - elif [ "$PSView" == "UDP" ]; then - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear}${CWhite} Show Open ${CGreen}(T)${CWhite}CP Ports | Show Open ${InvDkGray} ${CGreen}(U)${CWhite}DP ${CClear}${CWhite} Ports${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" - echo "" - if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then - echo -e "${InvGreen} ${CClear} ${CWhite}WAN0 IP: ${CGreen}$oldwan0ip${CClear}" - WANUnmap=$(nmap -sU $oldwan0ip | grep "open") - if [ -z "$WANUnmap" ]; then echo "None"; else nmap -sU $oldwan0ip | grep "open"; fi - echo "" - fi - echo -e "${InvGreen} ${CClear} ${CWhite}BR0 IP: ${CGreen}$oldlanip${CClear}" - LANUnmap=$(nmap -sU $oldlanip | grep "open") - if [ -z "$LANUnmap" ]; then echo "None"; else nmap -sU $oldlanip | grep "open"; fi - fi - - { echo 'Lastruntime="'"$(date)"'"' - echo 'LocalClockTest="'"$LocalClockTest"'"' - echo 'NetworkConnTest="'"$NetworkConnTest"'"' - echo 'NetworkResTest="'"$NetworkResTest"'"' - echo 'DigFuncTest="'"$DigFuncTest"'"' - echo 'CurlFuncTest="'"$CurlFuncTest"'"' - echo 'SpiderFuncTest="'"$SpiderFuncTest"'"' - echo 'SSLHandshakeTest="'"$SSLHandshakeTest"'"' - } > $DIAGRESPATH - - if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then - nmap $oldwan0ip -oN $NMAPWANRESPATH | grep "open" >/dev/null 2>&1 - nmap $oldwan0ip -sU -oN $NMAPUWANRESPATH | grep "open" >/dev/null 2>&1 - fi - - nmap $oldlanip -oN $NMAPLANRESPATH | grep "open" >/dev/null 2>&1 - nmap $oldlanip -sU -oN $NMAPULANRESPATH | grep "open" >/dev/null 2>&1 - - QueueNetworkDiag=0 - -else - - if [ "$LocalClockTest" == "Passed" ]; then - printf "\r${InvGreen} ${CClear} ${CWhite}Local Clock Test... ${CGreen}[Passed] ${CDkGray}| date > 1970${CClear}" - else - printf "\r${InvRed} ${CClear} ${CWhite}Local Clock Test... ${CRed}[Failed] ${CDkGray}| date > 1970${CClear}" - fi - echo "" - if [ "$NetworkConnTest" == "Passed" ]; then - printf "\r${InvGreen} ${CClear} ${CWhite}Network Connectivity Test... ${CGreen}[Passed] ${CDkGray}| ping 1.1.1.1 -c1 -W2${CClear}" - else - printf "\r${InvRed} ${CClear} ${CWhite}Network Connectivity Test... ${CRed}[Failed] ${CDkGray}| ping 1.1.1.1 -c1 -W2${CClear}" - fi - echo "" - if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then - if [ "$NetworkResTest" == "Passed" ]; then - printf "\r${InvGreen} ${CClear} ${CWhite}Network Resolution Test... ${CGreen}[Passed] ${CDkGray}| nslookup google.com 127.0.0.1${CClear}" - else - printf "\r${InvRed} ${CClear} ${CWhite}Network Resolution Test... ${CRed}[Failed] ${CDkGray}| nslookup google.com 127.0.0.1${CClear}" - fi - else - if [ "$NetworkResTest" == "Passed" ]; then - printf "\r${InvGreen} ${CClear} ${CWhite}Network Resolution Test... ${CGreen}[Passed] ${CDkGray}| nslookup google.com${CClear}" - else - printf "\r${InvRed} ${CClear} ${CWhite}Network Resolution Test... ${CRed}[Failed] ${CDkGray}| nslookup google.com${CClear}" - fi - fi - echo "" - if [ "$DigFuncTest" == "Passed" ]; then - printf "\r${InvGreen} ${CClear} ${CWhite}Dig Functionality Test... ${CGreen}[Passed] ${CDkGray}| dig google.com${CClear}" - else - printf "\r${InvRed} ${CClear} ${CWhite}Dig Functionality Test... ${CRed}[Failed] ${CDkGray}| dig google.com${CClear}" - fi - echo "" - if [ "$CurlFuncTest" == "Passed" ]; then - printf "\r${InvGreen} ${CClear} ${CWhite}Curl Functionality Test... ${CGreen}[Passed] ${CDkGray}| curl -Is http://www.google.com | head -n 1${CClear}" - else - printf "\r${InvRed} ${CClear} ${CWhite}Curl Functionality Test... ${CRed}[Failed] ${CDkGray}| curl -Is http://www.google.com | head -n 1${CClear}" - fi - echo "" - if [ "$SpiderFuncTest" == "Passed" ]; then - printf "\r${InvGreen} ${CClear} ${CWhite}Spider Functionality Test... ${CGreen}[Passed] ${CDkGray}| wget -q --spider http://google.com${CClear}" - else - printf "\r${InvRed} ${CClear} ${CWhite}Spider Functionality Test... ${CRed}[Failed] ${CDkGray}| wget -q --spider http://google.com${CClear}" - fi - echo "" - if [ "$SSLHandshakeTest" == "Passed" ]; then - printf "\r${InvGreen} ${CClear} ${CWhite}SSL Handshake Test... ${CGreen}[Passed] ${CDkGray}| nc -w3 8.8.8.8 443 && echo | openssl s_client -connect 8.8.8.8:443>${CClear}" - else - printf "\r${InvRed} ${CClear} ${CWhite}SSL Handshake Test... ${CRed}[Failed] ${CDkGray}| nc -w3 8.8.8.8 443 && echo | openssl s_client -connect 8.8.8.8:443>${CClear}" - fi - echo "" - echo "" - echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} NMAP Port Scan Results ${CClear}" - - if [ "$PSView" == "TCP" ]; then - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear}${CWhite} Show Open ${InvDkGray} ${CGreen}(T)${CWhite}CP ${CClear}${CWhite} Ports | Show Open ${CGreen}(U)${CWhite}DP Ports${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" - echo "" - if [ "$ScreenshotMode" == "1" ]; then - oldwan0ip="12.34.56.78" #demo - fi - if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then - echo -e "${InvGreen} ${CClear} ${CWhite}WAN0 IP: ${CGreen}$oldwan0ip${CClear}" - if [ ! -f $NMAPWANRESPATH ]; then - echo "None" - else - WANnmap=$(cat $NMAPWANRESPATH | grep "open") - if [ -z "$WANnmap" ]; then echo "None"; else cat $NMAPWANRESPATH | grep "open"; fi - fi - echo "" - fi - echo -e "${InvGreen} ${CClear} ${CWhite}BR0 IP: ${CGreen}$oldlanip${CClear}" - if [ ! -f $NMAPLANRESPATH ]; then - echo "None" - else - LANnmap=$(cat $NMAPLANRESPATH | grep "open") - if [ -z "$LANnmap" ]; then echo "None"; else cat $NMAPLANRESPATH | grep "open"; fi - fi - elif [ "$PSView" == "UDP" ]; then - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear}${CWhite} Show Open ${CGreen}(T)${CWhite}CP Ports | Show Open ${InvDkGray} ${CGreen}(U)${CWhite}DP ${CClear}${CWhite} Ports${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" - echo "" - if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then - echo -e "${InvGreen} ${CClear} ${CWhite}WAN0 IP: ${CGreen}$oldwan0ip${CClear}" - if [ ! -f $NMAPUWANRESPATH ]; then - echo "None" - else - WANUnmap=$(cat $NMAPUWANRESPATH | grep "open") - if [ -z "$WANUnmap" ]; then echo "None"; else cat $NMAPUWANRESPATH | grep "open"; fi - fi - echo "" - fi - echo -e "${InvGreen} ${CClear} ${CWhite}BR0 IP: ${CGreen}$oldlanip${CClear}" - if [ ! -f $NMAPULANRESPATH ]; then - echo "None" - else - LANUnmap=$(cat $NMAPULANRESPATH | grep "open") - if [ -z "$LANUnmap" ]; then echo "None"; else cat $NMAPULANRESPATH | grep "open"; fi - fi - fi -fi -} - -# ------------------------------------------------------------------------------------------------------------------------- - -# This function displays the stats UI for page 6 which includes top bandwidth connections for WAN, LAN and VPN -DisplayPage6() -{ - clear - if [ "$UpdateNotify" != "0" ]; then - echo -e "$UpdateNotify${CClear}" - fi - showheader - echo "" - echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} Top 10 Network Connections/Bandwidth Stats ${CClear}" - echo -e "${InvGreen} ${CClear}" - - if [ "$QueueNetworkConn" = "1" ] - then - #run network diags and save Results - printf "${InvGreen} ${CClear} ${CWhite}[Updating WAN( ) LAN( ) VPN( ) WG( ) Statistics ... Please stand by...]" - if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then - timeout 15 iftop -t -s 10 -i $WANIFNAME 2>&1 | sed '/^==/ q' > /jffs/addons/rtrmon.d/wanresult.txt - fi - printf "\r${InvGreen} ${CClear} ${CWhite}[Updating WAN(${CGreen}X${CWhite}) LAN( ) VPN( ) WG( ) Statistics ... Please stand by...]" - timeout 15 iftop -t -s 10 -i br0 2>&1 | sed '/^==/ q' > /jffs/addons/rtrmon.d/lanresult.txt - printf "\r${InvGreen} ${CClear} ${CWhite}[Updating WAN(${CGreen}X${CWhite}) LAN(${CGreen}X${CWhite}) VPN( ) WG( ) Statistics ... Please stand by...]" - - if [ "$vpn1on" == "True" ] || [ "$vpn2on" == "True" ] || [ "$vpn3on" == "True" ] || [ "$vpn4on" == "True" ] || [ "$vpn5on" == "True" ] - then - slot=0 - while [ "$slot" -ne 5 ] - do - slot="$((slot+1))" - selectedslot="vpn${slot}on" - eval selectedslot="\$${selectedslot}" - if [ "$selectedslot" = "True" ] && [ "$VPNSite2Site" = "0" ] - then - NVRAMVPNSLOTADDR=$($timeoutcmd$timeoutsec nvram get vpn_client"$slot"_addr) - NVRAMVPNSLOTIP=$(ping -c 1 -w 1 $NVRAMVPNSLOTADDR | awk -F '[()]' '/PING/ { print $2}') - if [ "$(echo "$NVRAMVPNSLOTIP" | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then - { echo 'Private Tunnel' - } > /jffs/addons/rtrmon.d/vpn${slot}result.txt - else - timeout 15 iftop -t -s 10 -i tun1$slot 2>&1 | sed '/^==/ q' > /jffs/addons/rtrmon.d/vpn${slot}result.txt - fi - fi - done - fi - - printf "\r${InvGreen} ${CClear} ${CWhite}[Updating WAN(${CGreen}X${CWhite}) LAN(${CGreen}X${CWhite}) VPN(${CGreen}X${CWhite}) WG( ) Statistics ... Please stand by...]" - - if [ "$wg1on" == "True" ] || [ "$wg2on" == "True" ] || [ "$wg3on" == "True" ] || [ "$wg4on" == "True" ] || [ "$wg5on" == "True" ] - then - slot=0 - while [ "$slot" -ne 5 ] - do - slot="$((slot+1))" - selectedslot="wg${slot}on" - eval selectedslot="\$${selectedslot}" - if [ "$selectedslot" = "True" ] && [ "$VPNSite2Site" = "0" ] - then - WGTUN="wgc$slot" - NVRAMWGSLOTADDR=$($timeoutcmd$timeoutsec nvram get "$WGTUN"_addr | cut -d '/' -f1) - - # Added based on suggestion from @ZebMcKayhan - ip rule add from $NVRAMWGSLOTADDR lookup $WGTUN prio 10 >/dev/null 2>&1 - - icanhazwgip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN" --request GET --url https://ipv4.icanhazip.com" - icanhazwgip="$(eval $icanhazwgip)" - if [ -z "$icanhazwgip" ] || echo "$icanhazwgip" | grep -qoE 'Internet|traffic|Error|error' - then - { echo 'Error determining WG$slot IP' - } > /jffs/addons/rtrmon.d/wgc${slot}result.txt - else - NVRAMWGIP="$icanhazwgip" - fi - - # Added based on suggestion from @ZebMcKayhan - ip rule del prio 10 >/dev/null 2>&1 - - if [ "$(echo "$NVRAMWGIP" | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then - { echo 'Private Tunnel' - } > /jffs/addons/rtrmon.d/wgc${slot}result.txt - else - timeout 15 iftop -t -s 10 -i wgc$slot 2>&1 | sed '/^==/ q' > /jffs/addons/rtrmon.d/wgc${slot}result.txt - fi - fi - done - fi - - printf "\r${InvGreen} ${CClear} ${CWhite}[Updating WAN(${CGreen}X${CWhite}) LAN(${CGreen}X${CWhite}) VPN(${CGreen}X${CWhite}) WG(${CGreen}X${CWhite}) Statistics ... Please stand by...]" - sleep 1 - printf "\r " - QueueNetworkConn=0 - testrun="$(date +%s)" - - if [ -z "${testrun:+xSETx}" ] - then - lastrun="Not Current" - else - currtime="$(date +%s)" - mindiffs="$(( ($currtime - $testrun)/60 ))" - lastrun="$mindiffs Minute(s) ago" - fi - - echo -e "\r${InvGreen} ${CClear} ${CWhite}Refresh ${CGreen}(C)${CWhite}urrent Statistics | Stats Age: ${CGreen}$lastrun${CClear}" - else - if [ -z "${testrun:+xSETx}" ] - then - lastrun="Not Current" - else - currtime="$(date +%s)" - mindiffs="$(( ($currtime - $testrun)/60 ))" - lastrun="$mindiffs Minute(s) ago" - fi - echo -e "${InvGreen} ${CClear} ${CWhite}Refresh ${CGreen}(C)${CWhite}urrent Statistics | Stats Age: ${CGreen}$lastrun${CClear}" - fi - - if [ "$NCView" == "WAN" ]; then - if [ "$vpn1on" == "True" ] || [ "$vpn2on" == "True" ] || [ "$vpn3on" == "True" ] || [ "$vpn4on" == "True" ] || [ "$vpn5on" == "True" ] || [ "$wg1on" == "True" ] || [ "$wg2on" == "True" ] || [ "$wg3on" == "True" ] || [ "$wg4on" == "True" ] || [ "$wg5on" == "True" ]; then - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear}${CWhite} View ${InvDkGray} ${CGreen}(W)${CWhite}AN ${CClear}${CWhite} | ${CGreen}(L)${CWhite}AN | ${CGreen}(V)${CWhite}PN | W${CGreen}(G)${CClear}" - else - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear}${CWhite} View ${InvDkGray} ${CGreen}(W)${CWhite}AN ${CClear}${CWhite} | ${CGreen}(L)${CWhite}AN${CClear}" - fi - - echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" - echo "" - echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} WAN ${CClear}" - - wansegments1=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==7 {print $1, $2, $4} NR==8 {print $1, $3}') - - line1="$(echo $wansegments1 | awk '{print $1}')" - dest1="$(echo $wansegments1 | awk '{print $2}')" - out1="$(echo $wansegments1 | awk '{print $3}')" - src1="$(echo $wansegments1 | awk '{print $4}')" - in1="$(echo $wansegments1 | awk '{print $5}')" - - wansegments2=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==9 {print $1, $2, $4} NR==10 {print $1, $3}') - - line2="$(echo $wansegments2 | awk '{print $1}')" - dest2="$(echo $wansegments2 | awk '{print $2}')" - out2="$(echo $wansegments2 | awk '{print $3}')" - src2="$(echo $wansegments2 | awk '{print $4}')" - in2="$(echo $wansegments2 | awk '{print $5}')" - - wansegments3=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==11 {print $1, $2, $4} NR==12 {print $1, $3}') - - line3="$(echo $wansegments3 | awk '{print $1}')" - dest3="$(echo $wansegments3 | awk '{print $2}')" - out3="$(echo $wansegments3 | awk '{print $3}')" - src3="$(echo $wansegments3 | awk '{print $4}')" - in3="$(echo $wansegments3 | awk '{print $5}')" - - wansegments4=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==13 {print $1, $2, $4} NR==14 {print $1, $3}') - - line4="$(echo $wansegments4 | awk '{print $1}')" - dest4="$(echo $wansegments4 | awk '{print $2}')" - out4="$(echo $wansegments4 | awk '{print $3}')" - src4="$(echo $wansegments4 | awk '{print $4}')" - in4="$(echo $wansegments4 | awk '{print $5}')" - - wansegments5=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==15 {print $1, $2, $4} NR==16 {print $1, $3}') - - line5="$(echo $wansegments5 | awk '{print $1}')" - dest5="$(echo $wansegments5 | awk '{print $2}')" - out5="$(echo $wansegments5 | awk '{print $3}')" - src5="$(echo $wansegments5 | awk '{print $4}')" - in5="$(echo $wansegments5 | awk '{print $5}')" - - wansegments6=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==17 {print $1, $2, $4} NR==18 {print $1, $3}') - - line6="$(echo $wansegments6 | awk '{print $1}')" - dest6="$(echo $wansegments6 | awk '{print $2}')" - out6="$(echo $wansegments6 | awk '{print $3}')" - src6="$(echo $wansegments6 | awk '{print $4}')" - in6="$(echo $wansegments6 | awk '{print $5}')" - - wansegments7=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==19 {print $1, $2, $4} NR==20 {print $1, $3}') - - line7="$(echo $wansegments7 | awk '{print $1}')" - dest7="$(echo $wansegments7 | awk '{print $2}')" - out7="$(echo $wansegments7 | awk '{print $3}')" - src7="$(echo $wansegments7 | awk '{print $4}')" - in7="$(echo $wansegments7 | awk '{print $5}')" - - wansegments8=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==21 {print $1, $2, $4} NR==22 {print $1, $3}') - - line8="$(echo $wansegments8 | awk '{print $1}')" - dest8="$(echo $wansegments8 | awk '{print $2}')" - out8="$(echo $wansegments8 | awk '{print $3}')" - src8="$(echo $wansegments8 | awk '{print $4}')" - in8="$(echo $wansegments8 | awk '{print $5}')" - - wansegments9=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==23 {print $1, $2, $4} NR==24 {print $1, $3}') - - line9="$(echo $wansegments9 | awk '{print $1}')" - dest9="$(echo $wansegments9 | awk '{print $2}')" - out9="$(echo $wansegments9 | awk '{print $3}')" - src9="$(echo $wansegments9 | awk '{print $4}')" - in9="$(echo $wansegments9 | awk '{print $5}')" - - wansegments10=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==25 {print $1, $2, $4} NR==26 {print $1, $3}') - - line10="$(echo $wansegments10 | awk '{print $1}')" - dest10="$(echo $wansegments10 | awk '{print $2}')" - out10="$(echo $wansegments10 | awk '{print $3}')" - src10="$(echo $wansegments10 | awk '{print $4}')" - in10="$(echo $wansegments10 | awk '{print $5}')" - - if [ "$line1" == "1" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line1 $dest1 <=> $src1" " Out: $out1 | In: $in1" - else - echo "No Data" - fi - - if [ "$line2" == "2" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line2 $dest2 <=> $src2" " Out: $out2 | In: $in2" - fi - - if [ "$line3" == "3" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line3 $dest3 <=> $src3" " Out: $out3 | In: $in3" - fi - - if [ "$line4" == "4" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line4 $dest4 <=> $src4" " Out: $out4 | In: $in4" - fi - - if [ "$line5" == "5" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line5 $dest5 <=> $src5" " Out: $out5 | In: $in5" - fi - - if [ "$line6" == "6" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line6 $dest6 <=> $src6" " Out: $out6 | In: $in6" - fi - - if [ "$line7" == "7" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line7 $dest7 <=> $src7" " Out: $out7 | In: $in7" - fi - - if [ "$line8" == "8" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line8 $dest8 <=> $src8" " Out: $out8 | In: $in8" - fi - - if [ "$line9" == "9" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line9 $dest9 <=> $src9" " Out: $out9 | In: $in9" - fi - - if [ "$line10" == "10" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" "$line10 $dest10 <=> $src10" " Out: $out10 | In: $in10" - fi - fi - - if [ "$NCView" == "LAN" ]; then - if [ "$vpn1on" == "True" ] || [ "$vpn2on" == "True" ] || [ "$vpn3on" == "True" ] || [ "$vpn4on" == "True" ] || [ "$vpn5on" == "True" ] || [ "$wg1on" == "True" ] || [ "$wg2on" == "True" ] || [ "$wg3on" == "True" ] || [ "$wg4on" == "True" ] || [ "$wg5on" == "True" ]; then - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear}${CWhite} View ${CGreen}(W)${CWhite}AN | ${InvDkGray} ${CGreen}(L)${CWhite}AN ${CClear}${CWhite} | ${CGreen}(V)${CWhite}PN | W${CGreen}(G)${CClear}" - else - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear}${CWhite} View ${CGreen}(W)${CWhite}AN | ${InvDkGray} ${CGreen}(L)${CWhite}AN ${CClear}" - fi - - echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" - echo "" - - echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} LAN ${CClear}" - - lansegments1=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==7 {print $1, $2, $4} NR==8 {print $1, $3}') - - line1="$(echo $lansegments1 | awk '{print $1}')" - dest1="$(echo $lansegments1 | awk '{print $2}')" - out1="$(echo $lansegments1 | awk '{print $3}')" - src1="$(echo $lansegments1 | awk '{print $4}')" - in1="$(echo $lansegments1 | awk '{print $5}')" - - lansegments2=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==9 {print $1, $2, $4} NR==10 {print $1, $3}') - - line2="$(echo $lansegments2 | awk '{print $1}')" - dest2="$(echo $lansegments2 | awk '{print $2}')" - out2="$(echo $lansegments2 | awk '{print $3}')" - src2="$(echo $lansegments2 | awk '{print $4}')" - in2="$(echo $lansegments2 | awk '{print $5}')" - - lansegments3=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==11 {print $1, $2, $4} NR==12 {print $1, $3}') - - line3="$(echo $lansegments3 | awk '{print $1}')" - dest3="$(echo $lansegments3 | awk '{print $2}')" - out3="$(echo $lansegments3 | awk '{print $3}')" - src3="$(echo $lansegments3 | awk '{print $4}')" - in3="$(echo $lansegments3 | awk '{print $5}')" - - lansegments4=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==13 {print $1, $2, $4} NR==14 {print $1, $3}') - - line4="$(echo $lansegments4 | awk '{print $1}')" - dest4="$(echo $lansegments4 | awk '{print $2}')" - out4="$(echo $lansegments4 | awk '{print $3}')" - src4="$(echo $lansegments4 | awk '{print $4}')" - in4="$(echo $lansegments4 | awk '{print $5}')" - - lansegments5=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==15 {print $1, $2, $4} NR==16 {print $1, $3}') - - line5="$(echo $lansegments5 | awk '{print $1}')" - dest5="$(echo $lansegments5 | awk '{print $2}')" - out5="$(echo $lansegments5 | awk '{print $3}')" - src5="$(echo $lansegments5 | awk '{print $4}')" - in5="$(echo $lansegments5 | awk '{print $5}')" - - lansegments6=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==17 {print $1, $2, $4} NR==18 {print $1, $3}') - - line6="$(echo $lansegments6 | awk '{print $1}')" - dest6="$(echo $lansegments6 | awk '{print $2}')" - out6="$(echo $lansegments6 | awk '{print $3}')" - src6="$(echo $lansegments6 | awk '{print $4}')" - in6="$(echo $lansegments6 | awk '{print $5}')" - - lansegments7=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==19 {print $1, $2, $4} NR==20 {print $1, $3}') - - line7="$(echo $lansegments7 | awk '{print $1}')" - dest7="$(echo $lansegments7 | awk '{print $2}')" - out7="$(echo $lansegments7 | awk '{print $3}')" - src7="$(echo $lansegments7 | awk '{print $4}')" - in7="$(echo $lansegments7 | awk '{print $5}')" - - lansegments8=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==21 {print $1, $2, $4} NR==22 {print $1, $3}') - - line8="$(echo $lansegments8 | awk '{print $1}')" - dest8="$(echo $lansegments8 | awk '{print $2}')" - out8="$(echo $lansegments8 | awk '{print $3}')" - src8="$(echo $lansegments8 | awk '{print $4}')" - in8="$(echo $lansegments8 | awk '{print $5}')" - - lansegments9=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==23 {print $1, $2, $4} NR==24 {print $1, $3}') - - line9="$(echo $lansegments9 | awk '{print $1}')" - dest9="$(echo $lansegments9 | awk '{print $2}')" - out9="$(echo $lansegments9 | awk '{print $3}')" - src9="$(echo $lansegments9 | awk '{print $4}')" - in9="$(echo $lansegments9 | awk '{print $5}')" - - lansegments10=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==25 {print $1, $2, $4} NR==26 {print $1, $3}') - - line10="$(echo $lansegments10 | awk '{print $1}')" - dest10="$(echo $lansegments10 | awk '{print $2}')" - out10="$(echo $lansegments10 | awk '{print $3}')" - src10="$(echo $lansegments10 | awk '{print $4}')" - in10="$(echo $lansegments10 | awk '{print $5}')" - - if [ "$line1" == "1" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line1 $dest1 <=> $src1" " Out: $out1 | In: $in1" - else - echo "No Data" - fi - - if [ "$line2" == "2" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line2 $dest2 <=> $src2" " Out: $out2 | In: $in2" - fi - - if [ "$line3" == "3" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line3 $dest3 <=> $src3" " Out: $out3 | In: $in3" - fi - - if [ "$line4" == "4" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line4 $dest4 <=> $src4" " Out: $out4 | In: $in4" - fi - - if [ "$line5" == "5" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line5 $dest5 <=> $src5" " Out: $out5 | In: $in5" - fi - - if [ "$line6" == "6" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line6 $dest6 <=> $src6" " Out: $out6 | In: $in6" - fi - - if [ "$line7" == "7" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line7 $dest7 <=> $src7" " Out: $out7 | In: $in7" - fi - - if [ "$line8" == "8" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line8 $dest8 <=> $src8" " Out: $out8 | In: $in8" - fi - - if [ "$line9" == "9" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line9 $dest9 <=> $src9" " Out: $out9 | In: $in9" - fi - - if [ "$line10" == "10" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" "$line10 $dest10 <=> $src10" " Out: $out10 | In: $in10" - fi - fi - - if [ "$NCView" = "VPN" ] - then - if [ "$vpn1on" == "True" ] || [ "$vpn2on" == "True" ] || [ "$vpn3on" == "True" ] || [ "$vpn4on" == "True" ] || [ "$vpn5on" == "True" ] || [ "$wg1on" == "True" ] || [ "$wg2on" == "True" ] || [ "$wg3on" == "True" ] || [ "$wg4on" == "True" ] || [ "$wg5on" == "True" ]; then - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear}${CWhite} View ${CGreen}(W)${CWhite}AN ${CWhite}| ${CGreen}(L)${CWhite}AN | ${InvDkGray} ${CGreen}(V)${CWhite}PN ${CClear} ${CWhite}| W${CGreen}(G)${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" - echo "" - - slot=0 - while [ "$slot" -ne 5 ] - do - slot="$((slot+1))" - selectedslot="vpn${slot}on" - eval selectedslot="\$${selectedslot}" - if [ "$selectedslot" = "True" ] && [ "$VPNSite2Site" = "0" ] - then - echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} VPN$slot ${CClear}" - - vpnsegments1=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==7 {print $1, $2, $4} NR==8 {print $1, $3}') - - line1="$(echo $vpnsegments1 | awk '{print $1}')" - dest1="$(echo $vpnsegments1 | awk '{print $2}')" - out1="$(echo $vpnsegments1 | awk '{print $3}')" - src1="$(echo $vpnsegments1 | awk '{print $4}')" - in1="$(echo $vpnsegments1 | awk '{print $5}')" - - vpnsegments2=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==9 {print $1, $2, $4} NR==10 {print $1, $3}') - - line2="$(echo $vpnsegments2 | awk '{print $1}')" - dest2="$(echo $vpnsegments2 | awk '{print $2}')" - out2="$(echo $vpnsegments2 | awk '{print $3}')" - src2="$(echo $vpnsegments2 | awk '{print $4}')" - in2="$(echo $vpnsegments2 | awk '{print $5}')" - - vpnsegments3=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==11 {print $1, $2, $4} NR==12 {print $1, $3}') - - line3="$(echo $vpnsegments3 | awk '{print $1}')" - dest3="$(echo $vpnsegments3 | awk '{print $2}')" - out3="$(echo $vpnsegments3 | awk '{print $3}')" - src3="$(echo $vpnsegments3 | awk '{print $4}')" - in3="$(echo $vpnsegments3 | awk '{print $5}')" - - vpnsegments4=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==13 {print $1, $2, $4} NR==14 {print $1, $3}') - - line4="$(echo $vpnsegments4 | awk '{print $1}')" - dest4="$(echo $vpnsegments4 | awk '{print $2}')" - out4="$(echo $vpnsegments4 | awk '{print $3}')" - src4="$(echo $vpnsegments4 | awk '{print $4}')" - in4="$(echo $vpnsegments4 | awk '{print $5}')" - - vpnsegments5=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==15 {print $1, $2, $4} NR==16 {print $1, $3}') - - line5="$(echo $vpnsegments5 | awk '{print $1}')" - dest5="$(echo $vpnsegments5 | awk '{print $2}')" - out5="$(echo $vpnsegments5 | awk '{print $3}')" - src5="$(echo $vpnsegments5 | awk '{print $4}')" - in5="$(echo $vpnsegments5 | awk '{print $5}')" - - vpnsegments6=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==17 {print $1, $2, $4} NR==18 {print $1, $3}') - - line6="$(echo $vpnsegments6 | awk '{print $1}')" - dest6="$(echo $vpnsegments6 | awk '{print $2}')" - out6="$(echo $vpnsegments6 | awk '{print $3}')" - src6="$(echo $vpnsegments6 | awk '{print $4}')" - in6="$(echo $vpnsegments6 | awk '{print $5}')" - - vpnsegments7=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==19 {print $1, $2, $4} NR==20 {print $1, $3}') - - line7="$(echo $vpnsegments7 | awk '{print $1}')" - dest7="$(echo $vpnsegments7 | awk '{print $2}')" - out7="$(echo $vpnsegments7 | awk '{print $3}')" - src7="$(echo $vpnsegments7 | awk '{print $4}')" - in7="$(echo $vpnsegments7 | awk '{print $5}')" - - vpnsegments8=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==21 {print $1, $2, $4} NR==22 {print $1, $3}') - - line8="$(echo $vpnsegments8 | awk '{print $1}')" - dest8="$(echo $vpnsegments8 | awk '{print $2}')" - out8="$(echo $vpnsegments8 | awk '{print $3}')" - src8="$(echo $vpnsegments8 | awk '{print $4}')" - in8="$(echo $vpnsegments8 | awk '{print $5}')" - - vpnsegments9=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==23 {print $1, $2, $4} NR==24 {print $1, $3}') - - line9="$(echo $vpnsegments9 | awk '{print $1}')" - dest9="$(echo $vpnsegments9 | awk '{print $2}')" - out9="$(echo $vpnsegments9 | awk '{print $3}')" - src9="$(echo $vpnsegments9 | awk '{print $4}')" - in9="$(echo $vpnsegments9 | awk '{print $5}')" - - vpnsegments10=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==25 {print $1, $2, $4} NR==26 {print $1, $3}') - - line10="$(echo $vpnsegments10 | awk '{print $1}')" - dest10="$(echo $vpnsegments10 | awk '{print $2}')" - out10="$(echo $vpnsegments10 | awk '{print $3}')" - src10="$(echo $vpnsegments10 | awk '{print $4}')" - in10="$(echo $vpnsegments10 | awk '{print $5}')" - - if [ "$line1" == "1" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line1 $dest1 <=> $src1" " Out: $out1 | In: $in1" - else - echo "No Data" - fi - - if [ "$line2" == "2" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line2 $dest2 <=> $src2" " Out: $out2 | In: $in2" - fi - - if [ "$line3" == "3" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line3 $dest3 <=> $src3" " Out: $out3 | In: $in3" - fi - - if [ "$line4" == "4" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line4 $dest4 <=> $src4" " Out: $out4 | In: $in4" - fi - - if [ "$line5" == "5" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line5 $dest5 <=> $src5" " Out: $out5 | In: $in5" - fi - - if [ "$line6" == "6" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line6 $dest6 <=> $src6" " Out: $out6 | In: $in6" - fi - - if [ "$line7" == "7" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line7 $dest7 <=> $src7" " Out: $out7 | In: $in7" - fi - - if [ "$line8" == "8" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line8 $dest8 <=> $src8" " Out: $out8 | In: $in8" - fi - - if [ "$line9" == "9" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line9 $dest9 <=> $src9" " Out: $out9 | In: $in9" - fi - - if [ "$line10" == "10" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" "$line10 $dest10 <=> $src10" " Out: $out10 | In: $in10" - fi - - echo "" - fi - done - fi - fi - -if [ "$NCView" = "WG" ] - then - if [ "$vpn1on" == "True" ] || [ "$vpn2on" == "True" ] || [ "$vpn3on" == "True" ] || [ "$vpn4on" == "True" ] || [ "$vpn5on" == "True" ] || [ "$wg1on" == "True" ] || [ "$wg2on" == "True" ] || [ "$wg3on" == "True" ] || [ "$wg4on" == "True" ] || [ "$wg5on" == "True" ]; then - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear}${CWhite} View ${CGreen}(W)${CWhite}AN ${CWhite}| ${CGreen}(L)${CWhite}AN | ${CGreen}(V)${CWhite}PN | ${InvDkGray} W${CGreen}(G) ${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" - echo "" - - slot=0 - while [ "$slot" -ne 5 ] - do - slot="$((slot+1))" - selectedslot="wg${slot}on" - eval selectedslot="\$${selectedslot}" - if [ "$selectedslot" = "True" ] && [ "$VPNSite2Site" = "0" ] - then - echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} WG$slot ${CClear}" - - wgsegments1=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==7 {print $1, $2, $4} NR==8 {print $1, $3}') - - line1="$(echo $wgsegments1 | awk '{print $1}')" - dest1="$(echo $wgsegments1 | awk '{print $2}')" - out1="$(echo $wgsegments1 | awk '{print $3}')" - src1="$(echo $wgsegments1 | awk '{print $4}')" - in1="$(echo $wgsegments1 | awk '{print $5}')" - - wgsegments2=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==9 {print $1, $2, $4} NR==10 {print $1, $3}') - - line2="$(echo $wgsegments2 | awk '{print $1}')" - dest2="$(echo $wgsegments2 | awk '{print $2}')" - out2="$(echo $wgsegments2 | awk '{print $3}')" - src2="$(echo $wgsegments2 | awk '{print $4}')" - in2="$(echo $wgsegments2 | awk '{print $5}')" - - wgsegments3=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==11 {print $1, $2, $4} NR==12 {print $1, $3}') - - line3="$(echo $wgsegments3 | awk '{print $1}')" - dest3="$(echo $wgsegments3 | awk '{print $2}')" - out3="$(echo $wgsegments3 | awk '{print $3}')" - src3="$(echo $wgsegments3 | awk '{print $4}')" - in3="$(echo $wgsegments3 | awk '{print $5}')" - - wgsegments4=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==13 {print $1, $2, $4} NR==14 {print $1, $3}') - - line4="$(echo $wgsegments4 | awk '{print $1}')" - dest4="$(echo $wgsegments4 | awk '{print $2}')" - out4="$(echo $wgsegments4 | awk '{print $3}')" - src4="$(echo $wgsegments4 | awk '{print $4}')" - in4="$(echo $wgsegments4 | awk '{print $5}')" - - wgsegments5=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==15 {print $1, $2, $4} NR==16 {print $1, $3}') - - line5="$(echo $wgsegments5 | awk '{print $1}')" - dest5="$(echo $wgsegments5 | awk '{print $2}')" - out5="$(echo $wgsegments5 | awk '{print $3}')" - src5="$(echo $wgsegments5 | awk '{print $4}')" - in5="$(echo $wgsegments5 | awk '{print $5}')" - - wgsegments6=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==17 {print $1, $2, $4} NR==18 {print $1, $3}') - - line6="$(echo $wgsegments6 | awk '{print $1}')" - dest6="$(echo $wgsegments6 | awk '{print $2}')" - out6="$(echo $wgsegments6 | awk '{print $3}')" - src6="$(echo $wgsegments6 | awk '{print $4}')" - in6="$(echo $wgsegments6 | awk '{print $5}')" - - wgsegments7=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==19 {print $1, $2, $4} NR==20 {print $1, $3}') - - line7="$(echo $wgsegments7 | awk '{print $1}')" - dest7="$(echo $wgsegments7 | awk '{print $2}')" - out7="$(echo $wgsegments7 | awk '{print $3}')" - src7="$(echo $wgsegments7 | awk '{print $4}')" - in7="$(echo $wgsegments7 | awk '{print $5}')" - - wgsegments8=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==21 {print $1, $2, $4} NR==22 {print $1, $3}') - - line8="$(echo $wgsegments8 | awk '{print $1}')" - dest8="$(echo $wgsegments8 | awk '{print $2}')" - out8="$(echo $wgsegments8 | awk '{print $3}')" - src8="$(echo $wgsegments8 | awk '{print $4}')" - in8="$(echo $wgsegments8 | awk '{print $5}')" - - wgsegments9=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==23 {print $1, $2, $4} NR==24 {print $1, $3}') - - line9="$(echo $wgsegments9 | awk '{print $1}')" - dest9="$(echo $wgsegments9 | awk '{print $2}')" - out9="$(echo $wgsegments9 | awk '{print $3}')" - src9="$(echo $wgsegments9 | awk '{print $4}')" - in9="$(echo $wgsegments9 | awk '{print $5}')" - - wgsegments10=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==25 {print $1, $2, $4} NR==26 {print $1, $3}') - - line10="$(echo $wgsegments10 | awk '{print $1}')" - dest10="$(echo $wgsegments10 | awk '{print $2}')" - out10="$(echo $wgsegments10 | awk '{print $3}')" - src10="$(echo $wgsegments10 | awk '{print $4}')" - in10="$(echo $wgsegments10 | awk '{print $5}')" - - if [ "$line1" == "1" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line1 $dest1 <=> $src1" " Out: $out1 | In: $in1" - else - echo "No Data" - fi - - if [ "$line2" == "2" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line2 $dest2 <=> $src2" " Out: $out2 | In: $in2" - fi - - if [ "$line3" == "3" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line3 $dest3 <=> $src3" " Out: $out3 | In: $in3" - fi - - if [ "$line4" == "4" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line4 $dest4 <=> $src4" " Out: $out4 | In: $in4" - fi - - if [ "$line5" == "5" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line5 $dest5 <=> $src5" " Out: $out5 | In: $in5" - fi - - if [ "$line6" == "6" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line6 $dest6 <=> $src6" " Out: $out6 | In: $in6" - fi - - if [ "$line7" == "7" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line7 $dest7 <=> $src7" " Out: $out7 | In: $in7" - fi - - if [ "$line8" == "8" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line8 $dest8 <=> $src8" " Out: $out8 | In: $in8" - fi - - if [ "$line9" == "9" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line9 $dest9 <=> $src9" " Out: $out9 | In: $in9" - fi - - if [ "$line10" == "10" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" "$line10 $dest10 <=> $src10" " Out: $out10 | In: $in10" - fi - - echo "" - fi - done - fi - fi - -} - -# ------------------------------------------------------------------------------------------------------------------------- -##------------------------------------------## -## Modified by ExtremeFiretop [2024-Aug-06] ## -##------------------------------------------## -# This function displays the stats UI for page 3 -DisplayPage7() -{ - clear - if [ "$UpdateNotify" != "0" ]; then - echo -e "$UpdateNotify${CClear}" - fi - showheader - # Create a temp arp table of connected wifi/lan clients - cat /proc/net/arp > /jffs/addons/rtrmon.d/temparp.txt - - # Force create the processed clients list file - touch /jffs/addons/rtrmon.d/processed_clients.txt - # Force create the processed clients list file for VLAN - touch /jffs/addons/rtrmon.d/processed_vlanclients.txt - - # Per @Stephen Harrington's sugguestion, check NVRAM to see if Wifi is turned on, else mark them as disabled - if [ "$FourBandCustom55624" == "True" ]; then - if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then - MaxSpeed5GhzNow=0 - else - MaxSpeed5GhzNow=$MaxSpeed5Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then - MaxSpeed52GhzNow=0 - else - MaxSpeed52GhzNow=$MaxSpeed5Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then - MaxSpeed6GhzNow=0 - else - MaxSpeed6GhzNow=$MaxSpeed6Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl3_radio) -eq 0 ]; then - MaxSpeed24GhzNow=0 - else - MaxSpeed24GhzNow=$MaxSpeed24Ghz - fi - elif [ "$FourBandCustom56624" == "True" ]; then - if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then - MaxSpeed5GhzNow=0 - else - MaxSpeed5GhzNow=$MaxSpeed5Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then - MaxSpeed6GhzNow=0 - else - MaxSpeed6GhzNow=$MaxSpeed6Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then - MaxSpeed62GhzNow=0 - else - MaxSpeed62GhzNow=$MaxSpeed6Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl3_radio) -eq 0 ]; then - MaxSpeed24GhzNow=0 - else - MaxSpeed24GhzNow=$MaxSpeed24Ghz - fi - elif [ "$ThreeBand2456" == "True" ]; then - if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then - MaxSpeed24GhzNow=0 - else - MaxSpeed24GhzNow=$MaxSpeed24Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then - MaxSpeed5GhzNow=0 - else - MaxSpeed5GhzNow=$MaxSpeed5Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then - MaxSpeed6GhzNow=0 - else - MaxSpeed6GhzNow=$MaxSpeed6Ghz - fi - elif [ "$ThreeBand2455" == "True" ]; then - if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then - MaxSpeed24GhzNow=0 - else - MaxSpeed24GhzNow=$MaxSpeed24Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then - MaxSpeed5GhzNow=0 - else - MaxSpeed5GhzNow=$MaxSpeed5Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then - MaxSpeed52GhzNow=0 - else - MaxSpeed52GhzNow=$MaxSpeed5Ghz - fi - else - if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then - MaxSpeed24GhzNow=0 - else - MaxSpeed24GhzNow=$MaxSpeed24Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then - MaxSpeed5GhzNow=0 - else - MaxSpeed5GhzNow=$MaxSpeed5Ghz - fi - fi - - if [ "$SortbyOpt" = "Name" ]; then - SortbyNum="1" - elif [ "$SortbyOpt" = "IP" ]; then - SortbyNum="2" - elif [ "$SortbyOpt" = "MAC" ]; then - SortbyNum="3" - else - SortbyNum="1" - fi - prevSortByOpt="$SortbyOpt" - - #Testing - #MaxSpeed24GhzNow=0 - #w24updown="UP" #testing - echo "" - echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} Attached Wireless + Wired Clients ${CClear}" - if [ "$SortbyOpt" = "Name" ]; then - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear}${CWhite} Sort By: ${InvDkGray}${CGreen} (!)${CWhite}Name ${CClear}${CWhite} | ${CGreen}(@)${CWhite}IP | ${CGreen}(#)${CWhite}MAC${CClear}" - elif [ "$SortbyOpt" = "IP" ]; then - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear}${CWhite} Sort By: ${CGreen} (!)${CWhite}Name | ${InvDkGray} ${CGreen}(@)${CWhite}IP ${CClear}${CWhite} | ${CGreen}(#)${CWhite}MAC${CClear}" - elif [ "$SortbyOpt" = "MAC" ]; then - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear}${CWhite} Sort By: ${CGreen} (!)${CWhite}Name | ${CGreen}(@)${CWhite}IP | ${InvDkGray} ${CGreen}(#)${CWhite}MAC ${CClear}" - fi - echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" - echo "" - - if [ "$MaxSpeed24GhzNow" != "0" ]; then - if [ "$w24updown" == "UP" ]; then - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 2.4GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname24 ${CClear}" - else - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 2.4GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname24 ${CClear}" - fi - attachedwificlients "$ifname24" - echo "" - else - echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 2.4GHz ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" - echo "" - fi - #Testing - #MaxSpeed5GhzNow=0 #testing - #w5updown="UP" #testing - if [ "$MaxSpeed5GhzNow" != "0" ]; then - if [ "$w5updown" == "UP" ]; then - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname5 ${CClear}" - else - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname5 ${CClear}" - fi - attachedwificlients "$ifname5" - echo "" - else - echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" - echo "" - fi - #Testing - #FourBandCustom55624="True" #testing - #MaxSpeed52GhzNow=0 #testing - #w52updown="UP" #testing - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then - if [ "$MaxSpeed52GhzNow" != "0" ]; then - if [ "$w52updown" == "UP" ]; then - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz (2) ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname52 ${CClear}" - else - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz (2) ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname52 ${CClear}" - fi - attachedwificlients "$ifname52" - #attachedwificlients "$ifname5" #testing - echo "" - else - echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz (2) ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" - echo "" - fi - fi - #Testing - #ThreeBand2456="True" #testing - #MaxSpeed6GhzNow=1 #testing - #w6updown="UP" #testing - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then - if [ "$MaxSpeed6GhzNow" != "0" ]; then - if [ "$w6updown" == "UP" ]; then - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname6 ${CClear}" - else - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname6 ${CClear}" - fi - attachedwificlients "$ifname6" - #attachedwificlients "$ifname5" #testing - echo "" - else - echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" - echo "" - fi - fi - #Testing - #FourBandCustom56624="True" #testing - #MaxSpeed62GhzNow=0 #testing - #w62updown="UP" #testing - if [ "$FourBandCustom56624" == "True" ]; then - if [ "$MaxSpeed62GhzNow" != "0" ]; then - if [ "$w62updown" == "UP" ]; then - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz (2) ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname62 ${CClear}" - else - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz (2) ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname62 ${CClear}" - fi - attachedwificlients "$ifname62" - #attachedwificlients "$ifname5" #testing - echo "" - else - echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz (2) ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" - echo "" - fi - fi - - # Guest Network Clients - Thanks to @ColinTaylor for this methodology of stepping through legit guest network interfaces - cp -f /jffs/addons/rtrmon.d/temparp.txt /jffs/addons/rtrmon.d/temparpvlan.txt - for guestiface in $(nvram get wl0_vifs) $(nvram get wl1_vifs) $(nvram get wl2_vifs) $(nvram get wl3_vifs) - do - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local Guest Wi-Fi ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $guestiface ${CClear}" - attachedguestclients "$guestiface" - echo "" - done - - for vlanlabels in $(nvram get apg_ifnames) - do - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local VLAN/AiMesh VLAN ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $vlanlabels ${CClear}" - attachedvlanclients "$vlanlabels" - echo "" - done - - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local LAN/Non-VLAN AiMesh ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: br0 ${CClear}" - #Remove non-LAN records - sed -i -e '/eth0/d' /jffs/addons/rtrmon.d/temparp.txt - sed -i -e '/IP address/d' /jffs/addons/rtrmon.d/temparp.txt - sed -i -e '/00:00:00:00:00:00/d' /jffs/addons/rtrmon.d/temparp.txt - sed -i -e '/0x0/d' /jffs/addons/rtrmon.d/temparp.txt - attachedlanclients - rm -f /jffs/addons/rtrmon.d/processed_clients.txt - rm -f /jffs/addons/rtrmon.d/processed_vlanclients.txt - rm -f /jffs/addons/rtrmon.d/temparp.txt - - #Testing - #FourBandCustom55624="False" #testing - #MaxSpeed52GhzNow=0 #testing - #w52updown="UP" #testing - #ThreeBand2456="False" #testing - #MaxSpeed6GhzNow=0 #testing - #w6updown="UP" #testing - #FourBandCustom56624="False" #testing - #MaxSpeed62GhzNow=0 #testing - #w62updown="UP" #testing -} - -# ------------------------------------------------------------------------------------------------------------------------- -# multiple DHCP lists can exist. Read through all lists and compile into a single list. - -read_all_dhcp_leases() { - # Include the merged lease file if it exists - local lease_files="/var/lib/misc/dnsmasq-*.leases /var/lib/misc/dnsmasq.leases" - if [ -f "/tmp/dnsmasq-merged.leases" ]; then - lease_files="$lease_files /tmp/dnsmasq-merged.leases" - fi - local all_leases - all_leases=$(cat $lease_files 2>/dev/null) - echo "$all_leases" -} - -# Unified MLD MAC retrieval logic: given the current dhcpleases and association MAC (in lowercase), -# determine the lookup MAC (which may be the MLD MAC if present). -get_lookup_mac() { - local maclower="$1" - local leases="$2" - local lookup_mac="$maclower" - local mld_line field_count mld_mac - mld_line=$(echo "$leases" | grep -i "$maclower" | head -n1) - if [ -n "$mld_line" ]; then - field_count=$(echo "$mld_line" | awk '{print NF; exit}') - if [ "$field_count" -ge 5 ]; then - mld_mac=$(echo "$mld_line" | awk '{print $5; exit}') - if [ -n "$mld_mac" ] && [ "$mld_mac" != "*" ]; then - lookup_mac=$(echo "$mld_mac" | awk '{print tolower($0)}') - fi - fi - fi - echo "$lookup_mac" -} - -# attachedwificlients pulls connected client info from wl, arp and nvram -attachedwificlients () -{ - iface="$1" - rm -f /jffs/addons/rtrmon.d/wificlients$iface.txt - wl -i $iface assoclist > /jffs/addons/rtrmon.d/wificlients$iface.txt - maxclientcount=$(cat /jffs/addons/rtrmon.d/wificlients$iface.txt | wc -l) - rm -f /jffs/addons/rtrmon.d/clientlist$iface.txt - dhcpleases="$(read_all_dhcp_leases)" - local clients=$(nvram get custom_clientlist) - local maxextractcount=$(echo "$clients" | awk -F'>>' '{count=0; for (i=1; i<=NF; i++) if ($i != "") count++; print count}') - - local clientcount=0 - while [ $clientcount -le $maxclientcount ] - do - clientname="" - conntime="" - clientip="" - paddedclientip="" - clientcount=$((clientcount+1)) - local clientmac=$(awk 'NR=='$clientcount' {print $2}' /jffs/addons/rtrmon.d/wificlients$iface.txt) - - if [ -z "$clientmac" ]; then - continue - fi - - networktime=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/in network/ {print $3}') 2>/dev/null - conntime=$(date -d@$networktime -u +%Hh:%Mm) 2>/dev/null - txtotalbytes=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/tx total bytes:/ {print $4}') 2>/dev/null - rxtotalbytes=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rx data bytes:/ {print $4}') 2>/dev/null - txratekbps=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rate of last tx pkt:/ {print $6}') 2>/dev/null - rxratekbps=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rate of last rx pkt:/ {print $6}') 2>/dev/null - sigstrength=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/smoothed rssi:/ {print $3}') 2>/dev/null - maclower=$(echo "$clientmac" | awk '{print tolower($0)}') 2>/dev/null - - # --- Unified MLD MAC retrieval logic --- - lookup_mac=$(get_lookup_mac "$maclower" "$dhcpleases") - - # Find IPs for the given MAC address in the ARP table - ips=$(grep "$maclower" "/jffs/addons/rtrmon.d/temparp.txt" | awk '{print $1}') 2>/dev/null - - # Iterate over the IPs to find the reachable one - for ip in $ips; do - # Check the status of the IP in the neighbor table - arp_status=$(ip neigh show | grep -w "$ip" | awk '{print $NF}') 2>/dev/null - - # Check if the current IP is reachable - if [ -z "$arp_status" ] || { [ "$arp_status" != "REACHABLE" ] && [ "$arp_status" != "DELAY" ]; }; then - if [ -z "$sigstrength" ]; then - conntime="STALE" - fi - continue - else - # Set the clientip to the current IP if it is reachable or delay - clientip="$ip" - break - fi - done - - # Fallback to using the ARP table if no reachable IP was found - if [ -z "$clientip" ]; then - clientip=$(cat /proc/net/arp | grep "$maclower" | awk '{print $1}' | sort | uniq | tail -n 1) 2>/dev/null - fi - - paddedclientip=$(echo "${clientip}" | grep -o -E '([0-9]*\.|[0-9]*)' | awk '{printf( "%03d\n", $1)}' | tr '\n' '.' | sed 's/.$//') 2>/dev/null - - #calcs - txtotalgb=$(echo $txtotalbytes | awk -v txb=$txtotalbytes 'BEGIN{printf "%0.2f\n", txb/1024/1024/1024}') 2>/dev/null - rxtotalgb=$(echo $rxtotalbytes | awk -v rxb=$rxtotalbytes 'BEGIN{printf "%0.2f\n", rxb/1024/1024/1024}') 2>/dev/null - txratembps=$(echo $txratekbps | awk -v txm=$txratekbps 'BEGIN{printf "%0.1f\n", txm/1000}') 2>/dev/null - rxratembps=$(echo $rxratekbps | awk -v rxm=$rxratekbps 'BEGIN{printf "%0.1f\n", rxm/1000}') 2>/dev/null - - local found=0 - local counter=0 - while [ $counter -le $maxextractcount ] - do - counter=$((counter+1)) - local clientextract="$(echo $clients | cut -d "<" -f$counter | cut -d ">" -f1,2)" - - if [ -z "$clientextract" ]; then - break - fi - - local client="$(echo $clientextract | awk -F ">" '{print $1}')" - local mac="$(echo $clientextract | awk -F ">" '{print $2}')" - - if [ "$mac" == "$clientmac" ]; then - clientname=$client - found=1 - break - fi - done - # Fallback to using dnsmasq.leases if no match found - if [ $found -ne 1 ]; then - clientname=$(echo "$dhcpleases" | grep -i "$lookup_mac" | awk '{print $4}') 2>/dev/null - if [ -z "$clientname" ] || [ "$clientname" == "*" ]; then - clientname="UNKNOWN" - fi - fi - if [ -n "$paddedclientip" ] && [ "$paddedclientip" != "000.000.000.000" ]; then - # Add the check for already processed clients - if grep -qi "$clientmac" /jffs/addons/rtrmon.d/processed_clients.txt; then - # Skip processing if the device was already handled - continue - else - echo "$clientmac" >> /jffs/addons/rtrmon.d/processed_clients.txt - fi - #delete entry from temparp table - sed -i -e '/'$maclower'/d' /jffs/addons/rtrmon.d/temparp.txt - echo "$clientname,$paddedclientip,$clientmac,$conntime,$txtotalgb,$rxtotalgb,$txratembps,$rxratembps,$sigstrength" >> /jffs/addons/rtrmon.d/clientlist$iface.txt - fi - done - - if [ -f "/jffs/addons/rtrmon.d/clientlist$iface.txt" ]; then - if [ $maxclientcount -ge 1 ]; then - sort -f -d -o /jffs/addons/rtrmon.d/clientlist$iface.txt -k "$SortbyNum" -t , /jffs/addons/rtrmon.d/clientlist$iface.txt 2>/dev/null - column -t -s',' -o' | ' -N Name,IP,MAC,Uptime,"TX GB","RX GB","TX Mbps","RX Mbps","Sig" /jffs/addons/rtrmon.d/clientlist$iface.txt | sed 's/^/ /' - else - echo -e " No Devices Connected" - fi - else - echo -e " No Devices Connected" - fi -} - -# ------------------------------------------------------------------------------------------------------------------------- -# attachedguestclients pulls connected client info from wl, arp and nvram -##------------------------------------------## -## Modified by ExtremeFiretop [2024-Aug-06] ## -##------------------------------------------## -attachedguestclients() { - iface="$1" - rm -f /jffs/addons/rtrmon.d/wificlients$iface.txt - wl -i $iface assoclist > /jffs/addons/rtrmon.d/wificlients$iface.txt - maxclientcount=$(cat /jffs/addons/rtrmon.d/wificlients$iface.txt | wc -l) - rm -f /jffs/addons/rtrmon.d/clientlist$iface.txt - dhcpleases="$(read_all_dhcp_leases)" - local clients=$(nvram get custom_clientlist) - local maxextractcount=$(echo "$clients" | awk -F'>>' '{count=0; for (i=1; i<=NF; i++) if ($i != "") count++; print count}') - - local clientcount=0 - while [ $clientcount -le $maxclientcount ] - do - clientname="" - conntime="" - clientip="" - paddedclientip="" - clientcount=$((clientcount+1)) - local clientmac=$(awk 'NR=='$clientcount' {print $2}' /jffs/addons/rtrmon.d/wificlients$iface.txt) - - if [ -z "$clientmac" ]; then - continue - fi - - networktime=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/in network/ {print $3}') 2>/dev/null - conntime=$(date -d@$networktime -u +%Hh:%Mm) 2>/dev/null - txtotalbytes=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/tx total bytes:/ {print $4}') 2>/dev/null - rxtotalbytes=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rx data bytes:/ {print $4}') 2>/dev/null - txratekbps=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rate of last tx pkt:/ {print $6}') 2>/dev/null - rxratekbps=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rate of last rx pkt:/ {print $6}') 2>/dev/null - sigstrength=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/smoothed rssi:/ {print $3}') 2>/dev/null - maclower=$(echo "$clientmac" | awk '{print tolower($0)}') 2>/dev/null - # --- Unified MLD MAC retrieval logic --- - lookup_mac=$(get_lookup_mac "$maclower" "$dhcpleases") - - # Find IPs for the given MAC address in the ARP table - ips=$(grep "$maclower" "/jffs/addons/rtrmon.d/temparp.txt" | awk '{print $1}') 2>/dev/null - - # Iterate over the IPs to find the reachable one - for ip in $ips; do - # Check the status of the IP in the neighbor table - arp_status=$(ip neigh show | grep -w "$ip" | awk '{print $NF}') 2>/dev/null - - # Check if the current IP is reachable - if [ -z "$arp_status" ] || { [ "$arp_status" != "REACHABLE" ] && [ "$arp_status" != "DELAY" ]; }; then - if [ -z "$sigstrength" ]; then - conntime="STALE" - fi - continue - else - # Set the clientip to the current IP if it is reachable or delay - clientip="$ip" - break - fi - done - - # Fallback to using the ARP table or DHCP leases if no reachable IP was found - if [ -z "$clientip" ]; then - # Try to get the last IP from the ARP table - clientip=$(cat /proc/net/arp | grep "$maclower" | awk '{print $1}' | sort | uniq | tail -n 1) 2>/dev/null - fi - - paddedclientip=$(echo "${clientip}" | grep -o -E '([0-9]*\.|[0-9]*)' | awk '{printf( "%03d\n", $1)}' | tr '\n' '.' | sed 's/.$//') 2>/dev/null - - #calcs - txtotalgb=$(echo $txtotalbytes | awk '{printf "%0.2f", $1/1024/1024/1024}') 2>/dev/null - rxtotalgb=$(echo $rxtotalbytes | awk '{printf "%0.2f", $1/1024/1024/1024}') 2>/dev/null - txratembps=$(echo $txratekbps | awk '{printf "%0.1f", $1/1000}') 2>/dev/null - rxratembps=$(echo $rxratekbps | awk '{printf "%0.1f", $1/1000}') 2>/dev/null - - local found=0 - local counter=0 - while [ $counter -le $maxextractcount ] - do - counter=$((counter+1)) - local clientextract="$(echo $clients | cut -d "<" -f$counter | cut -d ">" -f1,2)" - - if [ -z "$clientextract" ]; then - break - fi - - local client=$(echo $clientextract | awk -F ">" '{print $1}') - local mac=$(echo $clientextract | awk -F ">" '{print $2}') - - if [ "$mac" == "$clientmac" ]; then - clientname=$client - found=1 - break - fi - done - # Fallback to using dnsmasq.leases if no match found - if [ $found -ne 1 ]; then - clientname=$(echo "$dhcpleases" | grep -i "$lookup_mac" | awk '{print $4}') 2>/dev/null - if [ -z "$clientname" ] || [ "$clientname" == "*" ]; then - clientname="UNKNOWN" - fi - fi - if [ -n "$paddedclientip" ] && [ "$paddedclientip" != "000.000.000.000" ]; then - # Add the check for already processed clients - if grep -qi "$clientmac" /jffs/addons/rtrmon.d/processed_clients.txt; then - # Skip processing if the device was already handled - continue - else - echo "$clientmac" >> /jffs/addons/rtrmon.d/processed_clients.txt - fi - #delete entry from temparp table - sed -i -e '/'$maclower'/d' /jffs/addons/rtrmon.d/temparp.txt - echo "$clientname,$paddedclientip,$clientmac,$conntime,$txtotalgb,$rxtotalgb,$txratembps,$rxratembps,$sigstrength" >> /jffs/addons/rtrmon.d/clientlist$iface.txt - fi - done - - if [ -f "/jffs/addons/rtrmon.d/clientlist$iface.txt" ]; then - if [ $maxclientcount -ge 1 ]; then - sort -f -d -o /jffs/addons/rtrmon.d/clientlist$iface.txt -k "$SortbyNum" -t , /jffs/addons/rtrmon.d/clientlist$iface.txt 2>/dev/null - column -t -s',' -o' | ' -N Name,IP,MAC,Uptime,"TX GB","RX GB","TX Mbps","RX Mbps","Sig" /jffs/addons/rtrmon.d/clientlist$iface.txt | sed 's/^/ /' - else - echo -e " No Devices Connected" - fi - else - echo -e " No Devices Connected" - fi -} - -# ------------------------------------------------------------------------------------------------------------------------- -# attachedvlanclients pulls connected client info from wl, arp and nvram - -attachedvlanclients() { - iface="$1" - vlansfound=1 - maxclientcount=$(cat /jffs/addons/rtrmon.d/temparpvlan.txt | wc -l) - rm -f /jffs/addons/rtrmon.d/vlanclients$iface.txt - dhcpleases="$(read_all_dhcp_leases)" - local clients=$(nvram get custom_clientlist) - local maxextractcount=$(echo "$clients" | awk -F'>>' '{count=0; for (i=1; i<=NF; i++) if ($i != "") count++; print count}') - - local clientcount=0 - while [ $clientcount -le $maxclientcount ] - do - clientname="" - conntime="" - clientip="" - paddedclientip="" - interface_name="" - clientcount=$((clientcount+1)) - local clientmac=$(awk 'NR=='$clientcount' {print $4}' /jffs/addons/rtrmon.d/temparpvlan.txt | xargs) - - if [ -z "$clientmac" ]; then - continue - fi - - # Convert the MAC address to uppercase and store it in a new variable - macupper=$(echo "$clientmac" | tr 'a-f' 'A-F') - macprefix=$(echo "$macupper" | awk -F ':' '{print $1":"$2":"$3":"$4":"$5}') 2>/dev/null - clientbridgeid=$(awk 'NR=='$clientcount' {print $6}' /jffs/addons/rtrmon.d/temparpvlan.txt | xargs) - if [ -z "$clientbridgeid" ] || [ "$clientbridgeid" != "$iface" ]; then - continue - else - vlansfound=0 - fi - - interfaces=$(ip link show | grep -E 'wl|wlan' | awk -F: '{print $2}' | tr -d ' ') - for wirelessface in $interfaces; do - # Suppress both standard output and error from the wl command and check for the MAC - if wl -i "$wirelessface" assoclist 2>/dev/null | grep -iq "$macprefix"; then - # Save the interface name into the variable - interface_name="$wirelessface" - continue - fi - done - - networktime=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/in network/ {print $3}') 2>/dev/null - # Set conntime to "OFFLINE" if networktime is empty - if [ -z "$networktime" ]; then - conntime="AiMesh" - else - conntime=$(date -d@$networktime -u +%Hh:%Mm) 2>/dev/null - fi - txtotalbytes=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/tx total bytes:/ {print $4}') 2>/dev/null - rxtotalbytes=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/rx data bytes:/ {print $4}') 2>/dev/null - txratekbps=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/rate of last tx pkt:/ {print $6}') 2>/dev/null - rxratekbps=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/rate of last rx pkt:/ {print $6}') 2>/dev/null - sigstrength=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/smoothed rssi:/ {print $3}') 2>/dev/null - - # --- Unified MLD MAC lookup for VLAN clients --- - maclower=$(echo "$clientmac" | awk '{print tolower($0)}') 2>/dev/null - lookup_mac=$(get_lookup_mac "$maclower" "$dhcpleases") - - # Find IPs for the given MAC address in the ARP table - ips=$(grep "$clientmac" "/jffs/addons/rtrmon.d/temparp.txt" | awk '{print $1}') 2>/dev/null - - # Iterate over the IPs to find the reachable one - for ip in $ips; do - # Check the status of the IP in the neighbor table - arp_status=$(ip neigh show | grep -w "$ip" | awk '{print $NF}') 2>/dev/null - - # Check if the current IP is reachable - if [ -z "$arp_status" ] || { [ "$arp_status" != "REACHABLE" ] && [ "$arp_status" != "DELAY" ]; }; then - if [ -z "$sigstrength" ]; then - conntime="STALE" - fi - continue - else - # Set the clientip to the current IP if it is reachable or delay - clientip="$ip" - break - fi - done - - # Fallback to using the ARP table if no reachable IP was found - if [ -z "$clientip" ]; then - clientip=$(cat /proc/net/arp | grep "$clientmac" | awk '{print $1}' | sort | uniq | tail -n 1) 2>/dev/null - fi - - paddedclientip=$(echo "$clientip" | awk -F '.' '{printf "%03d.%03d.%03d.%03d\n", $1, $2, $3, $4}') 2>/dev/null - - #calcs - txtotalgb=$(echo $txtotalbytes | awk '{printf "%0.2f", $1/1024/1024/1024}') 2>/dev/null - rxtotalgb=$(echo $rxtotalbytes | awk '{printf "%0.2f", $1/1024/1024/1024}') 2>/dev/null - txratembps=$(echo $txratekbps | awk '{printf "%0.1f", $1/1000}') 2>/dev/null - rxratembps=$(echo $rxratekbps | awk '{printf "%0.1f", $1/1000}') 2>/dev/null - - local found=0 - local counter=0 - while [ $counter -le $maxextractcount ] - do - counter=$((counter+1)) - local clientextract="$(echo $clients | cut -d "<" -f$counter | cut -d ">" -f1,2)" - - if [ -z "$clientextract" ]; then - break - fi - - local client="$(echo $clientextract | awk -F ">" '{print $1}')" - local mac="$(echo $clientextract | awk -F ">" '{print $2}')" - - if [ "$mac" == "$macupper" ]; then - clientname=$client - found=1 - break - fi - - done - # Fallback to using dnsmasq.leases if no match found - if [ $found -ne 1 ]; then - clientname=$(echo "$dhcpleases" | grep -i "$lookup_mac" | awk '{print $4}') 2>/dev/null - if [ -z "$clientname" ] || [ "$clientname" == "*" ]; then - clientname="UNKNOWN" - fi - fi - if [ -n "$paddedclientip" ] && [ "$paddedclientip" != "000.000.000.000" ]; then - # Check if this MAC address has already been processed - if grep -q "$macupper" /jffs/addons/rtrmon.d/processed_vlanclients.txt && [ "$conntime" = "STALE" ]; then - continue # Skip processing this MAC address - else - # Mark this MAC as processed by adding it to the processed_macs_file - echo "$macupper" >> /jffs/addons/rtrmon.d/processed_vlanclients.txt - fi - #delete entry from temparp table - sed -i -e '/'$clientmac'/d' /jffs/addons/rtrmon.d/temparp.txt - if [ "$conntime" = "AiMesh" ]; then - echo "$clientname,$paddedclientip,$macupper,$conntime" >> /jffs/addons/rtrmon.d/vlanclients$iface.txt - else - echo "$clientname,$paddedclientip,$macupper,$conntime,$txtotalgb,$rxtotalgb,$txratembps,$rxratembps,$sigstrength" >> /jffs/addons/rtrmon.d/vlanclients$iface.txt - fi - fi - done - - if [ -f "/jffs/addons/rtrmon.d/vlanclients$iface.txt" ]; then - if [ $vlansfound -eq 0 ]; then - sort -f -d -t ',' -k "$SortbyNum" -k 4,4 /jffs/addons/rtrmon.d/vlanclients$iface.txt 2>/dev/null | \ - awk -F',' -v OFS=',' '{if ($4 ~ /AiMesh/) {a[i++]=$0} else {print $0}} END {for (j=0; j /tmp/vlanclients_sorted.txt - # Move sorted file back to original - mv /tmp/vlanclients_sorted.txt /jffs/addons/rtrmon.d/vlanclients$iface.txt - column -t -s',' -o' | ' -N Name,IP,MAC,Uptime,"TX GB","RX GB","TX Mbps","RX Mbps","Sig" /jffs/addons/rtrmon.d/vlanclients$iface.txt | sed 's/^/ /' - else - echo -e " No Devices Connected" - fi - else - echo -e " No Devices Connected" - fi -} - -# ------------------------------------------------------------------------------------------------------------------------- -# attachedlanclients pulls connected client info from wl, arp and nvram - -attachedlanclients () -{ - maxclientcount=$(cat /jffs/addons/rtrmon.d/temparp.txt | wc -l) - rm -f /jffs/addons/rtrmon.d/clientlistbr0.txt - dhcpleases="$(read_all_dhcp_leases)" - #find matchine client name - local clients=$(nvram get custom_clientlist) - local maxextractcount=$(echo "$clients" | awk -F'>>' '{count=0; for (i=1; i<=NF; i++) if ($i != "") count++; print count}') - - local clientcount=0 - while [ $clientcount -le $maxclientcount ] - do - clientname="" - paddedclientip="" - clientcount=$((clientcount+1)) - local clientmac=$(cat /jffs/addons/rtrmon.d/temparp.txt | awk 'NR=='$clientcount' {print $4}') 2>/dev/null - - if [ -z "$clientmac" ]; then - continue - fi - - local macupper=$(echo "$clientmac" | tr 'a-f' 'A-F') - - # Add the check for already processed clients - if grep -qi "$clients" /jffs/addons/rtrmon.d/processed_clients.txt; then - # Skip processing if the device was already handled - continue - else - echo "$macupper" >> /jffs/addons/rtrmon.d/processed_clients.txt - fi - - local counter=0 - local found=0 - while [ $counter -le $maxextractcount ] - do - counter=$((counter+1)) - local clientextract="$(echo $clients | cut -d "<" -f$counter | cut -d ">" -f1,2)" - - if [ -z "$clientextract" ]; then - continue - fi - - #clientip=$(cat /proc/net/arp | grep $clientmac | awk '{print $1}') - clientip=$(cat /jffs/addons/rtrmon.d/temparp.txt | grep $clientmac | awk '{print $1; exit}') 2>/dev/null - paddedclientip=$(echo "${clientip}" | grep -o -E '([0-9]*\.|[0-9]*)' | awk '{printf( "%03d\n", $1)}' | tr '\n' '.' | sed 's/.$//') 2>/dev/null - if [ -z $paddedclientip ]; then paddedclientip="000.000.000.000"; fi - - local client="$(echo $clientextract | awk -F ">" '{print $1}')" - local mac="$(echo $clientextract | awk -F ">" '{print $2}')" - - if [ "$mac" == "$macupper" ]; then - clientname=$client - found=1 - break - fi - done - # Fallback to using dnsmasq.leases if no match found - if [ $found -ne 1 ]; then - clientname=$(echo "$dhcpleases" | grep -i "$clientmac" | awk '{print $4}') - if [ -z "$clientname" ] || [ "$clientname" == "*" ]; then - clientname="UNKNOWN" - fi - fi - if [ -n "$paddedclientip" ] && [ "$paddedclientip" != "000.000.000.000" ]; then - echo "$clientname,$paddedclientip,$macupper" >> /jffs/addons/rtrmon.d/clientlistbr0.txt - fi - done - - if [ -f "/jffs/addons/rtrmon.d/clientlistbr0.txt" ]; then - if [ $maxclientcount -ge 1 ]; then - sort -f -d -o /jffs/addons/rtrmon.d/clientlistbr0.txt -k "$SortbyNum" -t , /jffs/addons/rtrmon.d/clientlistbr0.txt 2>/dev/null - column -t -s',' -o' | ' -N Name,IP,MAC /jffs/addons/rtrmon.d/clientlistbr0.txt | sed 's/^/ /' - else - echo -e " No Devices Connected" - fi - else - echo -e " No Devices Connected" - fi -} - -# ------------------------------------------------------------------------------------------------------------------------- -# GetVPNWGIPCITY is a function that gathers IP/City stats from all active VPN and WG connections - -GetVPNWGIPCITY() -{ - - vpn1slot=1 - VPN1State="$(_VPN_GetClientState_ ${vpn1slot})" - if [ -z "$VPN1State" ]; then VPN1State=0; fi # to catch possible wireguard interference - if [ "$VPN1State" -eq 2 ]; then - if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing VPN1 Stats...]"; fi - TUN1="tun1"$vpn1slot - NVRAMVPN1ADDR=$($timeoutcmd$timeoutsec nvram get vpn_client"$vpn1slot"_addr) - NVRAMVPN1IP=$(ping -c 1 -w 1 $NVRAMVPN1ADDR | awk -F '[()]' '/PING/ { print $2}') - - if [ "$NVRAMVPN1ADDR" != "$oldvpn1ADDR" ]; then - oldvpn1ip=$(curl --silent --fail --interface $TUN1 --request GET --url https://ipv4.icanhazip.com) - if [ -z $oldvpn1ip ]; then oldvpn1ip=$NVRAMVPN1IP; fi - oldvpn1ADDR=$NVRAMVPN1ADDR - fi - - if [ "$(echo $NVRAMVPN1IP | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then - oldvpn1ip=$NVRAMVPN1IP - oldvpn1city="Private Network" - elif [ "$vpn1ip" != "$oldvpn1ip" ]; then - oldvpn1city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldvpn1ip | jq --raw-output .city" - oldvpn1city="$(eval $oldvpn1city)"; if echo $oldvpn1city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldvpn1city="Undetermined"; fi - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: API call made to determine geolocation of VPN$vpn1slot: $oldvpn1ip ($oldvpn1city)" >> $LOGFILE - fi - - vpn1ip=$oldvpn1ip - vpn1city=$oldvpn1city - vpn1on="True" - - else - vpn1on="False" - fi - - #Check to see if there's a secondary VPN connection - vpn2slot=2 - VPN2State="$(_VPN_GetClientState_ ${vpn2slot})" - if [ -z "$VPN2State" ]; then VPN2State=0; fi # to catch possible wireguard interference - if [ "$VPN2State" -eq 2 ]; then - if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing VPN2 Stats...]"; fi - TUN2="tun1"$vpn2slot - NVRAMVPN2ADDR=$($timeoutcmd$timeoutsec nvram get vpn_client"$vpn2slot"_addr) - NVRAMVPN2IP=$(ping -c 1 -w 1 $NVRAMVPN2ADDR | awk -F '[()]' '/PING/ { print $2}') - - if [ "$NVRAMVPN2ADDR" != "$oldvpn2ADDR" ]; then - oldvpn2ip=$(curl --silent --fail --interface $TUN2 --request GET --url https://ipv4.icanhazip.com) - if [ -z $oldvpn2ip ]; then oldvpn2ip=$NVRAMVPN2IP; fi - oldvpn2ADDR=$NVRAMVPN2ADDR - fi - - if [ "$(echo $NVRAMVPN2IP | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then - oldvpn2ip=$NVRAMVPN2IP - oldvpn2city="Private Network" - elif [ "$vpn2ip" != "$oldvpn2ip" ]; then - oldvpn2city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldvpn2ip | jq --raw-output .city" - oldvpn2city="$(eval $oldvpn2city)"; if echo $oldvpn2city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldvpn2city="Undetermined"; fi - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: API call made to determine geolocation of VPN$vpn2slot: $oldvpn2ip ($oldvpn2city)" >> $LOGFILE - fi - - vpn2ip=$oldvpn2ip - vpn2city=$oldvpn2city - vpn2on="True" - - else - vpn5on="False" - fi - - #Check to see if there's a third VPN connection - vpn3slot=3 - VPN3State="$(_VPN_GetClientState_ ${vpn3slot})" - if [ -z "$VPN3State" ]; then VPN3State=0; fi # to catch possible wireguard interference - if [ "$VPN3State" -eq 2 ]; then - if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing VPN3 Stats...]"; fi - TUN3="tun1"$vpn3slot - NVRAMVPN3ADDR=$($timeoutcmd$timeoutsec nvram get vpn_client"$vpn3slot"_addr) - NVRAMVPN3IP=$(ping -c 1 -w 1 $NVRAMVPN3ADDR | awk -F '[()]' '/PING/ { print $2}') - - if [ "$NVRAMVPN3ADDR" != "$oldvpn3ADDR" ]; then - oldvpn3ip=$(curl --silent --fail --interface $TUN3 --request GET --url https://ipv4.icanhazip.com) - if [ -z $oldvpn3ip ]; then oldvpn3ip=$NVRAMVPN3IP; fi - oldvpn3ADDR=$NVRAMVPN3ADDR - fi - - if [ "$(echo $NVRAMVPN3IP | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then - oldvpn3ip=$NVRAMVPN3IP - oldvpn3city="Private Network" - elif [ "$vpn3ip" != "$oldvpn3ip" ]; then - oldvpn3city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldvpn3ip | jq --raw-output .city" - oldvpn3city="$(eval $oldvpn3city)"; if echo $oldvpn3city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldvpn3city="Undetermined"; fi - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: API call made to determine geolocation of VPN$vpn3slot: $oldvpn3ip ($oldvpn3city)" >> $LOGFILE - fi - - vpn3ip=$oldvpn3ip - vpn3city=$oldvpn3city - vpn3on="True" - - else - vpn3on="False" - fi - - #Check to see if there's a fourth VPN connection - vpn4slot=4 - VPN4State="$(_VPN_GetClientState_ ${vpn4slot})" - if [ -z "$VPN4State" ]; then VPN4State=0; fi # to catch possible wireguard interference - if [ "$VPN4State" -eq 2 ]; then - if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing VPN4 Stats...]"; fi - TUN4="tun1"$vpn4slot - NVRAMVPN4ADDR=$($timeoutcmd$timeoutsec nvram get vpn_client"$vpn4slot"_addr) - NVRAMVPN4IP=$(ping -c 1 -w 1 $NVRAMVPN4ADDR | awk -F '[()]' '/PING/ { print $2}') - - if [ "$NVRAMVPN4ADDR" != "$oldvpn4ADDR" ]; then - oldvpn4ip=$(curl --silent --fail --interface $TUN4 --request GET --url https://ipv4.icanhazip.com) - if [ -z $oldvpn4ip ]; then oldvpn4ip=$NVRAMVPN4IP; fi - oldvpn4ADDR=$NVRAMVPN4ADDR - fi - - if [ "$(echo $NVRAMVPN4IP | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then - oldvpn4ip=$NVRAMVPN4IP - oldvpn4city="Private Network" - elif [ "$vpn4ip" != "$oldvpn4ip" ]; then - oldvpn4city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldvpn4ip | jq --raw-output .city" - oldvpn4city="$(eval $oldvpn4city)"; if echo $oldvpn4city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldvpn4city="Undetermined"; fi - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: API call made to determine geolocation of VPN$vpn4slot: $oldvpn4ip ($oldvpn4city)" >> $LOGFILE - fi - - vpn4ip=$oldvpn4ip - vpn4city=$oldvpn4city - vpn4on="True" - - else - vpn4on="False" - fi - - #Check to see if there's a fifth VPN connection - vpn5slot=5 - VPN5State="$(_VPN_GetClientState_ ${vpn5slot})" - if [ -z "$VPN5State" ]; then VPN5State=0; fi # to catch possible wireguard interference - if [ "$VPN5State" -eq 2 ]; then - if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing VPN5 Stats...]"; fi - TUN5="tun1"$vpn5slot - NVRAMVPN5ADDR=$($timeoutcmd$timeoutsec nvram get vpn_client"$vpn5slot"_addr) - NVRAMVPN5IP=$(ping -c 1 -w 1 $NVRAMVPN5ADDR | awk -F '[()]' '/PING/ { print $2}') - - if [ "$NVRAMVPN5ADDR" != "$oldvpn5ADDR" ]; then - oldvpn5ip=$(curl --silent --fail --interface $TUN5 --request GET --url https://ipv4.icanhazip.com) - if [ -z $oldvpn5ip ]; then oldvpn5ip=$NVRAMVPN5IP; fi - oldvpn5ADDR=$NVRAMVPN5ADDR - fi - - if [ "$(echo $NVRAMVPN5IP | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then - oldvpn5ip=$NVRAMVPN5IP - oldvpn5city="Private Network" - elif [ "$vpn5ip" != "$oldvpn5ip" ]; then - oldvpn5city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldvpn5ip | jq --raw-output .city" - oldvpn5city="$(eval $oldvpn5city)"; if echo $oldvpn5city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldvpn5city="Undetermined"; fi - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: API call made to determine geolocation of VPN$vpn5slot: $oldvpn5ip ($oldvpn5city)" >> $LOGFILE - fi - - vpn5ip=$oldvpn5ip - vpn5city=$oldvpn5city - vpn5on="True" - - else - vpn5on="False" - fi - - #Check to see if there's a WGC1 connection - wg1slot=1 - WG1State="$(_WG_GetClientState_ ${wg1slot})" - if [ -z "$WG1State" ]; then WG1State=0; fi - if [ "$WG1State" -eq 2 ]; then - WGTUN1="wgc$wg1slot" - WGTUN1_IP=$($timeoutcmd$timeoutsec nvram get "$WGTUN1"_addr | cut -d '/' -f1) - WG1ADDR=$($timeoutcmd$timeoutsec nvram get "$WGTUN1"_ep_addr) - NVRAMWG1IP=$(ping -c 1 -w 1 $WGTUN1_IP | awk -F '[()]' '/PING/ { print $2}') - if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing WG1 Stats...]"; fi - if [ "$WG1ADDR" != "$oldwg1ADDR" ] || [ "$wg1ip" = "0.0.0.0" ]; then - # Added based on suggestion from @ZebMcKayhan - ip rule add from $WGTUN1_IP lookup $WGTUN1 prio 10 >/dev/null 2>&1 - oldwg1ip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN1" --request GET --url https://ipv4.icanhazip.com" - oldwg1ip="$(eval $oldwg1ip)" - if [ -z "$oldwg1ip" ] || echo "$oldwg1ip" | grep -qoE 'Internet|traffic|Error|error' - then - oldwg1ip="$NVRAMWG1IP" - fi - oldwg1ADDR=$WG1ADDR - # Added based on suggestion from @ZebMcKayhan - ip rule del prio 10 >/dev/null 2>&1 - fi - - if [ "$(echo "$oldwg1ip" | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then - oldwg1ip="$NVRAMWG1IP" - oldwg1city="Private Network" - elif [ "$wg1ip" != "$oldwg1ip" ]; then - oldwg1city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldwg1ip | jq --raw-output .city" - oldwg1city="$(eval $oldwg1city)"; if echo $oldwg1city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldwg1city="Undetermined"; fi - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - API call made to determine geolocation of WG$wg1slot: $oldwg1ip ($oldwg1city)" >> $LOGFILE - fi - - wg1ip="$oldwg1ip" - wg1city="$oldwg1city" - wg1on="True" - - else - wg1on="False" - fi - - #Check to see if there's a WGC2 connection - wg2slot=2 - WG2State="$(_WG_GetClientState_ ${wg2slot})" - if [ -z "$WG2State" ]; then WG2State=0; fi - if [ "$WG2State" -eq 2 ]; then - WGTUN2="wgc$wg2slot" - WGTUN2_IP=$($timeoutcmd$timeoutsec nvram get "$WGTUN2"_addr | cut -d '/' -f1) - WG2ADDR=$($timeoutcmd$timeoutsec nvram get "$WGTUN2"_ep_addr) - NVRAMWG2IP=$(ping -c 1 -w 1 $WGTUN2_IP | awk -F '[()]' '/PING/ { print $2}') - if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing WG2 Stats...]"; fi - if [ "$WG2ADDR" != "$oldwg2ADDR" ] || [ "$wg2ip" = "0.0.0.0" ]; then - # Added based on suggestion from @ZebMcKayhan - ip rule add from $WGTUN2_IP lookup $WGTUN2 prio 10 >/dev/null 2>&1 - oldwg2ip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN2" --request GET --url https://ipv4.icanhazip.com" - oldwg2ip="$(eval $oldwg2ip)" - if [ -z "$oldwg2ip" ] || echo "$oldwg2ip" | grep -qoE 'Internet|traffic|Error|error' - then - oldwg2ip="$NVRAMWG2IP" - fi - oldwg2ADDR=$WG2ADDR - # Added based on suggestion from @ZebMcKayhan - ip rule del prio 10 >/dev/null 2>&1 - fi - - if [ "$(echo "$oldwg2ip" | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then - oldwg2ip="$NVRAMWG2IP" - oldwg2city="Private Network" - elif [ "$wg2ip" != "$oldwg2ip" ]; then - oldwg2city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldwg2ip | jq --raw-output .city" - oldwg2city="$(eval $oldwg2city)"; if echo $oldwg2city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldwg2city="Undetermined"; fi - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - API call made to determine geolocation of WG$wg2slot: $oldwg2ip ($oldwg2city)" >> $LOGFILE - fi - - wg2ip="$oldwg2ip" - wg2city="$oldwg2city" - wg2on="True" - - else - wg2on="False" - fi - - #Check to see if there's a WGC3 connection - wg3slot=3 - WG3State="$(_WG_GetClientState_ ${wg3slot})" - if [ -z "$WG3State" ]; then WG3State=0; fi - if [ "$WG3State" -eq 2 ]; then - WGTUN3="wgc$wg3slot" - WGTUN3_IP=$($timeoutcmd$timeoutsec nvram get "$WGTUN3"_addr | cut -d '/' -f1) - WG3ADDR=$($timeoutcmd$timeoutsec nvram get "$WGTUN3"_ep_addr) - NVRAMWG3IP=$(ping -c 1 -w 1 $WGTUN3_IP | awk -F '[()]' '/PING/ { print $2}') - if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing WG3 Stats...]"; fi - if [ "$WG3ADDR" != "$oldwg3ADDR" ] || [ "$wg3ip" = "0.0.0.0" ]; then - # Added based on suggestion from @ZebMcKayhan - ip rule add from $WGTUN3_IP lookup $WGTUN3 prio 10 >/dev/null 2>&1 - oldwg3ip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN3" --request GET --url https://ipv4.icanhazip.com" - oldwg3ip="$(eval $oldwg3ip)" - if [ -z "$oldwg3ip" ] || echo "$oldwg3ip" | grep -qoE 'Internet|traffic|Error|error' - then - oldwg3ip="$NVRAMWG3IP" - fi - oldwg3ADDR=$WG3ADDR - # Added based on suggestion from @ZebMcKayhan - ip rule del prio 10 >/dev/null 2>&1 - fi - - if [ "$(echo "$oldwg3ip" | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then - oldwg3ip="$NVRAMWG3IP" - oldwg3city="Private Network" - elif [ "$wg3ip" != "$oldwg3ip" ]; then - oldwg3city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldwg3ip | jq --raw-output .city" - oldwg3city="$(eval $oldwg3city)"; if echo $oldwg3city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldwg3city="Undetermined"; fi - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - API call made to determine geolocation of WG$wg3slot: $oldwg3ip ($oldwg3city)" >> $LOGFILE - fi - - wg3ip="$oldwg3ip" - wg3city="$oldwg3city" - wg3on="True" - - else - wg3on="False" - fi - - #Check to see if there's a WGC4 connection - wg4slot=4 - WG14State="$(_WG_GetClientState_ ${wg4slot})" - if [ -z "$WG4State" ]; then WG4State=0; fi - if [ "$WG4State" -eq 2 ]; then - WGTUN4="wgc$wg4slot" - WGTUN4_IP=$($timeoutcmd$timeoutsec nvram get "$WGTUN4"_addr | cut -d '/' -f1) - WG4ADDR=$($timeoutcmd$timeoutsec nvram get "$WGTUN4"_ep_addr) - NVRAMWG4IP=$(ping -c 1 -w 1 $WGTUN4_IP | awk -F '[()]' '/PING/ { print $2}') - if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing WG4 Stats...]"; fi - if [ "$WG4ADDR" != "$oldwg4ADDR" ] || [ "$wg4ip" = "0.0.0.0" ]; then - # Added based on suggestion from @ZebMcKayhan - ip rule add from $WGTUN4_IP lookup $WGTUN4 prio 10 >/dev/null 2>&1 - oldwg4ip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN4" --request GET --url https://ipv4.icanhazip.com" - oldwg4ip="$(eval $oldwg4ip)" - if [ -z "$oldwg4ip" ] || echo "$oldwg4ip" | grep -qoE 'Internet|traffic|Error|error' - then - oldwg4ip="$NVRAMWG4IP" - fi - oldwg4ADDR=$WG4ADDR - # Added based on suggestion from @ZebMcKayhan - ip rule del prio 10 >/dev/null 2>&1 - fi - - if [ "$(echo "$oldwg4ip" | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then - oldwg4ip="$NVRAMWG4IP" - oldwg4city="Private Network" - elif [ "$wg4ip" != "$oldwg4ip" ]; then - oldwg4city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldwg4ip | jq --raw-output .city" - oldwg4city="$(eval $oldwg4city)"; if echo $oldwg1city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldwg4city="Undetermined"; fi - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - API call made to determine geolocation of WG$wg4slot: $oldwg4ip ($oldwg4city)" >> $LOGFILE - fi - - wg4ip="$oldwg4ip" - wg4city="$oldwg4city" - wg4on="True" - - else - wg4on="False" - fi - - #Check to see if there's a WGC5 connection - wg5slot=5 - WG5State="$(_WG_GetClientState_ ${wg5slot})" - if [ -z "$WG5State" ]; then WG5State=0; fi - if [ "$WG5State" -eq 2 ]; then - WGTUN5="wgc$wg5slot" - WGTUN5_IP=$($timeoutcmd$timeoutsec nvram get "$WGTUN5"_addr | cut -d '/' -f1) - WG5ADDR=$($timeoutcmd$timeoutsec nvram get "$WGTUN5"_ep_addr) - NVRAMWG5IP=$(ping -c 1 -w 1 $WGTUN5_IP | awk -F '[()]' '/PING/ { print $2}') - if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing WG5 Stats...]"; fi - if [ "$WG5ADDR" != "$oldwg5ADDR" ] || [ "$wg5ip" = "0.0.0.0" ]; then - # Added based on suggestion from @ZebMcKayhan - ip rule add from $WGTUN5_IP lookup $WGTUN5 prio 10 >/dev/null 2>&1 - oldwg5ip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN5" --request GET --url https://ipv4.icanhazip.com" - oldwg5ip="$(eval $oldwg5ip)" - if [ -z "$oldwg5ip" ] || echo "$oldwg5ip" | grep -qoE 'Internet|traffic|Error|error' - then - oldwg5ip="$NVRAMWG5IP" - fi - oldwg5ADDR=$WG5ADDR - # Added based on suggestion from @ZebMcKayhan - ip rule del prio 10 >/dev/null 2>&1 - fi - - if [ "$(echo "$oldwg5ip" | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then - oldwg5ip="$NVRAMWG5IP" - oldwg5city="Private Network" - elif [ "$wg5ip" != "$oldwg5ip" ]; then - oldwg5city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldwg5ip | jq --raw-output .city" - oldwg5city="$(eval $oldwg5city)"; if echo $oldwg5city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldwg5city="Undetermined"; fi - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - API call made to determine geolocation of WG$wg5slot: $oldwg5ip ($oldwg5city)" >> $LOGFILE - fi - - wg5ip="$oldwg5ip" - wg5city="$oldwg5city" - wg5on="True" - - else - wg5on="False" - fi - -} - -# ------------------------------------------------------------------------------------------------------------------------- -# GetVPNWGStats is a function that calculates connection stats from all active VPN and WG connections - -GetVPNWGStats() -{ - - if [ "$vpn1on" == "True" ]; then - oldvpntxrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn1slot/status 2>/dev/null) - oldvpnrxbytes="$(echo $oldvpntxrxbytes | cut -d' ' -f1)" - oldvpntxbytes="$(echo $oldvpntxrxbytes | cut -d' ' -f2)" - if [ -z $oldvpnrxbytes ]; then oldvpnrxbytes=0; fi - if [ -z $oldvpntxbytes ]; then oldvpntxbytes=0; fi - - if [ $oldvpnrxbytes -le 0 ]; then - oldvpnrxbytes=0 - elif [ $oldvpntxbytes -le 0 ]; then - oldvpntxbytes=0 - fi - fi - - if [ "$vpn2on" == "True" ]; then - oldvpn2txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn2slot/status 2>/dev/null) - oldvpn2rxbytes="$(echo $oldvpn2txrxbytes | cut -d' ' -f1)" - oldvpn2txbytes="$(echo $oldvpn2txrxbytes | cut -d' ' -f2)" - if [ -z $oldvpn2rxbytes ]; then oldvpn2rxbytes=0; fi - if [ -z $oldvpn2txbytes ]; then oldvpn2txbytes=0; fi - - if [ $oldvpn2rxbytes -le 0 ]; then - oldvpn2rxbytes=0 - elif [ $oldvpn2txbytes -le 0 ]; then - oldvpn2txbytes=0 - fi - fi - - if [ "$vpn3on" == "True" ]; then - oldvpn3txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn3slot/status 2>/dev/null) - oldvpn3rxbytes="$(echo $oldvpn3txrxbytes | cut -d' ' -f1)" - oldvpn3txbytes="$(echo $oldvpn3txrxbytes | cut -d' ' -f2)" - if [ -z $oldvpn3rxbytes ]; then oldvpn3rxbytes=0; fi - if [ -z $oldvpn3txbytes ]; then oldvpn3txbytes=0; fi - - if [ $oldvpn3rxbytes -le 0 ]; then - oldvpn3rxbytes=0 - elif [ $oldvpn3txbytes -le 0 ]; then - oldvpn3txbytes=0 - fi - fi - - if [ "$vpn4on" == "True" ]; then - oldvpn4txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn4slot/status 2>/dev/null) - oldvpn4rxbytes="$(echo $oldvpn4txrxbytes | cut -d' ' -f1)" - oldvpn4txbytes="$(echo $oldvpn4txrxbytes | cut -d' ' -f2)" - if [ -z $oldvpn4rxbytes ]; then oldvpn4rxbytes=0; fi - if [ -z $oldvpn4txbytes ]; then oldvpn4txbytes=0; fi - - if [ $oldvpn4rxbytes -le 0 ]; then - oldvpn4rxbytes=0 - elif [ $oldvpn4txbytes -le 0 ]; then - oldvpn4txbytes=0 - fi - fi - - if [ "$vpn5on" == "True" ]; then - oldvpn5txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn5slot/status 2>/dev/null) - oldvpn5rxbytes="$(echo $oldvpn5txrxbytes | cut -d' ' -f1)" - oldvpn5txbytes="$(echo $oldvpn5txrxbytes | cut -d' ' -f2)" - if [ -z $oldvpn5rxbytes ]; then oldvpn5rxbytes=0; fi - if [ -z $oldvpn5txbytes ]; then oldvpn5txbytes=0; fi - - if [ $oldvpn5rxbytes -le 0 ]; then - oldvpn5rxbytes=0 - elif [ $oldvpn5txbytes -le 0 ]; then - oldvpn5txbytes=0 - fi - fi - - # Check the wireguard connections - if [ "$wg1on" == "True" ]; then - oldwg1txrxbytes=$(wg show wgc1 transfer) - oldwg1rxbytes="$(echo $oldwg1txrxbytes | cut -d' ' -f3)" - oldwg1txbytes="$(echo $oldwg1txrxbytes | cut -d' ' -f2)" - if [ -z $oldwg1rxbytes ] || [ $oldwg1rxbytes -le 0 ]; then oldwg1rxbytes=0; fi - if [ -z $oldwg1txbytes ] || [ $oldwg1txbytes -le 0 ]; then oldwg1txbytes=0; fi - fi - - if [ "$wg2on" == "True" ]; then - oldwg2txrxbytes=$(wg show wgc2 transfer) - oldwg2rxbytes="$(echo $oldwg2txrxbytes | cut -d' ' -f3)" - oldwg2txbytes="$(echo $oldwg2txrxbytes | cut -d' ' -f2)" - if [ -z $oldwg2rxbytes ] || [ $oldwg2rxbytes -le 0 ]; then oldwg2rxbytes=0; fi - if [ -z $oldwg2txbytes ] || [ $oldwg2txbytes -le 0 ]; then oldwg2txbytes=0; fi - fi - - if [ "$wg3on" == "True" ]; then - oldwg3txrxbytes=$(wg show wgc3 transfer) - oldwg3rxbytes="$(echo $oldwg3txrxbytes | cut -d' ' -f3)" - oldwg3txbytes="$(echo $oldwg3txrxbytes | cut -d' ' -f2)" - if [ -z $oldwg3rxbytes ] || [ $oldwg3rxbytes -le 0 ]; then oldwg3rxbytes=0; fi - if [ -z $oldwg3txbytes ] || [ $oldwg3txbytes -le 0 ]; then oldwg3txbytes=0; fi - fi - - if [ "$wg4on" == "True" ]; then - oldwg4txrxbytes=$(wg show wgc4 transfer) - oldwg4rxbytes="$(echo $oldwg4txrxbytes | cut -d' ' -f3)" - oldwg4txbytes="$(echo $oldwg4txrxbytes | cut -d' ' -f2)" - if [ -z $oldwg4rxbytes ] || [ $oldwg4rxbytes -le 0 ]; then oldwg4rxbytes=0; fi - if [ -z $oldwg4txbytes ] || [ $oldwg4txbytes -le 0 ]; then oldwg4txbytes=0; fi - fi - - if [ "$wg5on" == "True" ]; then - oldwg5txrxbytes=$(wg show wgc5 transfer) - oldwg5rxbytes="$(echo $oldwg5txrxbytes | cut -d' ' -f3)" - oldwg5txbytes="$(echo $oldwg5txrxbytes | cut -d' ' -f2)" - if [ -z $oldwg5rxbytes ] || [ $oldwg5rxbytes -le 0 ]; then oldwg5rxbytes=0; fi - if [ -z $oldwg5txbytes ] || [ $oldwg5txbytes -le 0 ]; then oldwg5txbytes=0; fi - fi - -} - -# ------------------------------------------------------------------------------------------------------------------------- -# VPN_GetClientState was created by @Martinski in many thanks to trying to eliminate unknown operand errors due to null -# vpn_clientX_state values - -_VPN_GetClientState_() -{ - if [ $# -lt 1 ] || [ -z "$1" ] || ! echo "$1" | grep -qE "^[1-5]$" - then echo "**ERROR**" ; return 1 ; fi - - local nvramVal="$($timeoutcmd$timeoutsec nvram get "vpn_client${1}_state")" - if [ -z "$nvramVal" ] || ! echo "$nvramVal" | grep -qE "^[0-9]$" - then echo "0" ; else echo "$nvramVal" ; fi - return 0 -} - -# ------------------------------------------------------------------------------------------------------------------------- -# WG_GetClientState is based off _VPN_GetClientState_ - -_WG_GetClientState_() -{ - if [ $# -lt 1 ] || [ -z "$1" ] || ! echo "$1" | grep -qE "^[1-5]$" - then echo "**ERROR**" ; return 1 ; fi - - # Inspiration from ZebMcKayHan's WGC Watchdog Script - last_handshake=$(wg show wgc$1 latest-handshakes | awk '{print $2}') >/dev/null 2>&1 - - if [ -z $last_handshake ] - then - WGnvramVal=0 #disconnected - else - WGnvramVal=2 #connected - fi - - #local WGnvramVal="$($timeoutcmd$timeoutsec nvram get "wgc${1}_enable")" - if [ -z "$WGnvramVal" ] || ! echo "$WGnvramVal" | grep -qE "^[+-]?[0-9]$" - then echo "0" ; else echo "$WGnvramVal" ; fi - return 0 -} - -##-------------------------------------## -## Added by Martinski W. [2024-Nov-02] ## -##-------------------------------------## -_SetUpTimeoutCmdVars_() -{ - # If the timeout utility is available then use it # - if [ -z "${timeoutcmd:+xSETx}" ] && [ -f "/opt/bin/timeout" ] - then - timeoutcmd="timeout " - timeoutsec="10" - timeoutlng="60" - fi -} - -##-------------------------------------## -## Added by Martinski W. [2024-Nov-02] ## -##-------------------------------------## -_SetLAN_HostName_() -{ - [ -z "${LAN_HostName:+xSETx}" ] && \ - LAN_HostName="$($timeoutcmd$timeoutsec nvram get lan_hostname)" -} - -_GetLAN_HostName_() -{ _SetLAN_HostName_ ; echo "$LAN_HostName" ; } - -trap '_IgnoreKeypresses_ OFF ; exit 0' EXIT INT QUIT ABRT TERM - -# ------------------------------------------------------------------------------------------------------------------------- -# Begin Commandline Argument Gatekeeper and Configuration Utility Functionality -# ------------------------------------------------------------------------------------------------------------------------- -##----------------------------------------## -## Modified by Martinski W. [2024-Nov-02] ## -##----------------------------------------## - -DEBUG=; set -x # uncomment/comment to enable/disable debug mode -{ # uncomment/comment to enable/disable debug mode - - _SetUpTimeoutCmdVars_ - _SetLAN_HostName_ - - # Create the necessary folder/file structure for RTRMON under /jffs/addons - if [ ! -d "/jffs/addons/rtrmon.d" ]; then - mkdir -p "/jffs/addons/rtrmon.d" - fi - - # Check for Updates - updatecheck - - RouterModel="$($timeoutcmd$timeoutsec nvram get odmpid)" - [ -z "$RouterModel" ] && RouterModel="$($timeoutcmd$timeoutsec nvram get productid)" - - FWVER="$($timeoutcmd$timeoutsec nvram get firmver | tr -d '.')" - BUILDNO="$($timeoutcmd$timeoutsec nvram get buildno)" - EXTENDNO="$($timeoutcmd$timeoutsec nvram get extendno)" - if [ -z "$EXTENDNO" ]; then EXTENDNO=0; fi - FWBUILD="${FWVER}.${BUILDNO}_${EXTENDNO}" - - # Check for advanced router Features - FourBandCustom55624="False" - FourBandCustom56624="False" - ThreeBand2456="False" - ThreeBand2455="False" - - if [ "$RouterModel" = "GT-AXE16000" ] || [ "$RouterModel" = "GT-BE98" ]; then - FourBandCustom55624="True" - fi - if [ "$RouterModel" = "GT-BE98_Pro" ]; then - FourBandCustom56624="True" - fi - if [ "$RouterModel" = "GT-AXE11000" ] || [ "$RouterModel" = "ZenWiFi_ET8" ] || [ "$RouterModel" = "RT-BE96U" ] || [ "$RouterModel" = "RT-BE92U" ]; then - ThreeBand2456="True" - fi - if [ "$RouterModel" = "GT-AX11000_Pro" ] || [ "$RouterModel" = "GT-AX11000" ] || [ "$RouterModel" = "ZenWiFi_Pro_XT12" ] || [ "$RouterModel" = "ZenWiFi_XT8" ]; then - ThreeBand2455="True" - fi - - # Check what mode the router is in: 1=Router, 2=AP, 3=iMesh Node # - OpsMode="$($timeoutcmd$timeoutsec nvram get sw_mode)" - #OpsMode=3 - - # Check and see if any commandline option is being used - if [ $# -eq 0 ] || [ -z "$1" ] - then - clear - echo "" - echo "RTRMON v$Version" - echo "" - echo "Exiting due to missing commandline options!" - echo "(run 'rtrmon.sh -h' for help)" - echo "" - echo -e "${CClear}" - exit 0 - fi - - # Check and see if an invalid commandline option is being used - if [ "$1" = "-h" ] || [ "$1" = "-help" ] || [ "$1" = "-config" ] || [ "$1" = "-setup" ] || \ - [ "$1" = "-monitor" ] || [ "$1" = "-reset" ] || [ "$1" = "-update" ] || \ - [ "$1" = "-screen" ] || [ "$1" = "-uninstall" ] || [ "$1" = "-log" ] || \ - { [ $# -gt 1 ] && [ "$2" = "-now" ] ; } || { [ $# -gt 2 ] &&[ "$3" = "-now" ] ; } - then - clear - else - clear - echo "" - echo "RTRMON v$Version" - echo "" - echo "Exiting due to invalid commandline options!" - echo "(run 'rtrmon.sh -h' for help)" - echo "" - echo -e "${CClear}" - exit 0 - fi - - # Check to see if the help option is being called - if [ "$1" == "-h" ] || [ "$1" == "-help" ] - then - clear - echo "" - echo "RTRMON v$Version Commandline Option Usage:" - echo "" - echo "rtrmon.sh -h | -help" - echo "rtrmon.sh -log" - echo "rtrmon.sh -config" - echo "rtrmon.sh -update" - echo "rtrmon.sh -setup" - echo "rtrmon.sh -uninstall" - echo "rtrmon.sh -screen" - echo "rtrmon.sh -monitor" - echo "rtrmon.sh -screen/-monitor X" - echo "rtrmon.sh -screen (X) -now" - echo "" - echo " -h | -help (this output)" - echo " -log (display the current log contents)" - echo " -config (configuration utility)" - echo " -update (script update utility)" - echo " -setup (setup/dependencies utility)" - echo " -uninstall (uninstall utility)" - echo " -screen (normal router monitoring using the screen utility)" - echo " -monitor (normal router monitoring operations)" - echo " -screen/-monitor X (X = display screen 1-6 upon execution)" - echo " -screen -now (bypass screen instructions and 5 sec timer)" - echo "" - echo " Examples:" - echo " rtrmon -screen -now (bypass screen timer directly into monitor mode)" - echo " rtrmon -screen 2 (jump to page 2 upon execution using screen)" - echo " rtrmon -screen 3 -now (bypass timer and jump to page 3 using screen)" - echo " rtrmon -monitor 4 (jump to page 4 in monitoring mode)" - echo "" - echo -e "${CClear}" - exit 0 - fi - - # Check to see if the log option is being called, and display through nano - if [ "$1" == "-log" ] - then - vlogs - exit 0 - fi - - # Check to see if the configuration option is being called, and run through setup utility - if [ "$1" == "-config" ] - then - vconfig - echo -e "${CClear}" - exit 0 - fi - - # Check to see if the update option is being called - if [ "$1" == "-update" ] - then - vupdate - echo -e "${CClear}" - exit 0 - fi - - # Check to see if the install option is being called - if [ "$1" = "-setup" ] - then - vsetup - exit 0 - fi - - # Check to see if the uninstall option is being called - if [ "$1" = "-uninstall" ] - then - vuninstall - echo -e "${CClear}" - exit 0 - fi - - # Check to see if the -now parameter is being called to bypass the screen timer - if [ $# -gt 1 ] && [ "$2" = "-now" ] - then - bypassScreenTimer=1 - elif [ $# -gt 2 ] && [ "$3" = "-now" ] - then - bypassScreenTimer2=1 - fi - - # Check to see if the screen option is being called and run operations normally using the screen utility - if [ "$1" = "-screen" ] - then - screen -wipe >/dev/null 2>&1 # Kill any dead screen sessions - sleep 1 - ScreenSess="$(screen -ls | grep "rtrmon" | awk '{print $1}' | cut -d . -f 1)" - if [ -z "$ScreenSess" ] - then - if [ "$bypassScreenTimer" = "1" ] - then - screen -dmS "rtrmon" $APPPATH -monitor - sleep 1 - screen -r rtrmon - elif [ "$bypassScreenTimer2" = "1" ] - then - if [ $# -lt 2 ] || [ -z "$2" ]; then - screen -dmS "rtrmon" $APPPATH -monitor - elif [ "$2" -ge 1 ] && [ "$2" -le 6 ]; then - screen -dmS "rtrmon" $APPPATH -monitor $2 - else - screen -dmS "rtrmon" $APPPATH -monitor - fi - sleep 1 - screen -r rtrmon - else - clear - echo -e "${CClear}Executing ${CGreen}RTRMON v$Version ${CClear}using the SCREEN utility...${CClear}" - echo "" - echo -e "${CClear}IMPORTANT:${CClear}" - echo -e "${CClear}In order to keep RTRMON running in the background,${CClear}" - echo -e "${CClear}properly exit the SCREEN session by using: ${CGreen}CTRL-A + D${CClear}" - echo "" - if [ $# -lt 2 ] || [ -z "$2" ]; then - screen -dmS "rtrmon" $APPPATH -monitor - elif [ "$2" -ge 1 ] && [ "$2" -le 6 ]; then - screen -dmS "rtrmon" $APPPATH -monitor $2 - else - screen -dmS "rtrmon" $APPPATH -monitor - fi - sleep 2 - echo -e "${CClear}Switching to the SCREEN session in T-5 sec...${CClear}" - echo -e "${CClear}" - spinner 5 - screen -r rtrmon - exit 0 - fi - else - if [ "$bypassScreenTimer" = "1" ]; then - sleep 1 - else - clear - echo -e "${CClear}Connecting to existing ${CGreen}RTRMON v$Version ${CClear}SCREEN session...${CClear}" - echo "" - echo -e "${CClear}IMPORTANT:${CClear}" - echo -e "${CClear}In order to keep RTRMON running in the background,${CClear}" - echo -e "${CClear}properly exit the SCREEN session by using: ${CGreen}CTRL-A + D${CClear}" - echo "" - echo -e "${CClear}Switching to the SCREEN session in T-5 sec...${CClear}" - echo -e "${CClear}" - spinner 5 - fi - fi - screen -dr $ScreenSess - exit 0 - fi - - # Check to see if the monitor option is being called and run operations normally - if [ "$1" = "-monitor" ] - then - clear - if [ -f "$CFGPATH" ] && [ -f "/opt/bin/column" ] && [ -f "/opt/bin/timeout" ] && [ -f "/opt/sbin/screen" ] && [ -f "/opt/bin/nmap" ] && [ -f "/opt/bin/jq" ] && [ -f "/opt/bin/iftop" ] - then - printf "\r\033[0K${InvYellow} ${CClear} Please wait..." ; _ConsumeKeypressBuffer_ - source "$CFGPATH" - - if [ -f /root/.config/ookla/speedtest-cli.json ] && \ - [ ! -f /jffs/addons/rtrmon.d/speedtest-cli.json ] - then - cp -fp /root/.config/ookla/speedtest-cli.json /jffs/addons/rtrmon.d/speedtest-cli.json 2>/dev/null - fi - - if [ ! -d "/root/.config/ookla" ] - then - mkdir -p "/root/.config/ookla" - [ -f /jffs/addons/rtrmon.d/speedtest-cli.json ] && \ - cp -fp /jffs/addons/rtrmon.d/speedtest-cli.json /root/.config/ookla/speedtest-cli.json 2>/dev/null - fi - - NextPage="$([ $# -gt 1 ] && echo "$2" | tr -d -c 1-7 || echo)" - if [ -z "$NextPage" ]; then NextPage=1 ; fi - - # Per @Stephen Harrington's suggestion, check NVRAM to see if WiFi is turned on, else mark them as disabled - if [ "$FourBandCustom55624" == "True" ]; then - if [ "$($timeoutcmd$timeoutsec nvram get wl0_radio)" -eq 0 ]; then - MaxSpeed5GhzNow=0 - else - MaxSpeed5GhzNow=$MaxSpeed5Ghz - fi - if [ "$($timeoutcmd$timeoutsec nvram get wl1_radio)" -eq 0 ]; then - MaxSpeed52GhzNow=0 - else - MaxSpeed52GhzNow=$MaxSpeed5Ghz - fi - if [ "$($timeoutcmd$timeoutsec nvram get wl2_radio)" -eq 0 ]; then - MaxSpeed6GhzNow=0 - else - MaxSpeed6GhzNow=$MaxSpeed6Ghz - fi - if [ "$($timeoutcmd$timeoutsec nvram get wl3_radio)" -eq 0 ]; then - MaxSpeed24GhzNow=0 - else - MaxSpeed24GhzNow=$MaxSpeed24Ghz - fi - elif [ "$FourBandCustom56624" == "True" ]; then - if [ "$($timeoutcmd$timeoutsec nvram get wl0_radio)" -eq 0 ]; then - MaxSpeed5GhzNow=0 - else - MaxSpeed5GhzNow=$MaxSpeed5Ghz - fi - if [ "$($timeoutcmd$timeoutsec nvram get wl1_radio)" -eq 0 ]; then - MaxSpeed6GhzNow=0 - else - MaxSpeed6GhzNow=$MaxSpeed6Ghz - fi - if [ "$($timeoutcmd$timeoutsec nvram get wl2_radio)" -eq 0 ]; then - MaxSpeed62GhzNow=0 - else - MaxSpeed62GhzNow=$MaxSpeed6Ghz - fi - if [ "$($timeoutcmd$timeoutsec nvram get wl3_radio)" -eq 0 ]; then - MaxSpeed24GhzNow=0 - else - MaxSpeed24GhzNow=$MaxSpeed24Ghz - fi - elif [ "$ThreeBand2456" == "True" ]; then - if [ "$($timeoutcmd$timeoutsec nvram get wl0_radio)" -eq 0 ]; then - MaxSpeed24GhzNow=0 - else - MaxSpeed24GhzNow=$MaxSpeed24Ghz - fi - if [ "$($timeoutcmd$timeoutsec nvram get wl1_radio)" -eq 0 ]; then - MaxSpeed5GhzNow=0 - else - MaxSpeed5GhzNow=$MaxSpeed5Ghz - fi - if [ "$($timeoutcmd$timeoutsec nvram get wl2_radio)" -eq 0 ]; then - MaxSpeed6GhzNow=0 - else - MaxSpeed6GhzNow=$MaxSpeed6Ghz - fi - elif [ "$ThreeBand2455" == "True" ]; then - if [ "$($timeoutcmd$timeoutsec nvram get wl0_radio)" -eq 0 ]; then - MaxSpeed24GhzNow=0 - else - MaxSpeed24GhzNow=$MaxSpeed24Ghz - fi - if [ "$($timeoutcmd$timeoutsec nvram get wl1_radio)" -eq 0 ]; then - MaxSpeed5GhzNow=0 - else - MaxSpeed5GhzNow=$MaxSpeed5Ghz - fi - if [ "$($timeoutcmd$timeoutsec nvram get wl2_radio)" -eq 0 ]; then - MaxSpeed52GhzNow=0 - else - MaxSpeed52GhzNow=$MaxSpeed5Ghz - fi - else - if [ "$($timeoutcmd$timeoutsec nvram get wl0_radio)" -eq 0 ]; then - MaxSpeed24GhzNow=0 - else - MaxSpeed24GhzNow=$MaxSpeed24Ghz - fi - if [ "$($timeoutcmd$timeoutsec nvram get wl1_radio)" -eq 0 ]; then - MaxSpeed5GhzNow=0 - else - MaxSpeed5GhzNow=$MaxSpeed5Ghz - fi - fi - - else - echo -e "${CRed}Error: RTRMON is not configured or does not have all the required dependencies${CClear}" - echo -e "${CRed}installed. Launching 'rtrmon -setup' to install dependencies/complete setup!${CClear}" - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - ERROR: RTRMON is not configured/missing dependencies. Please run the setup tool." >> $LOGFILE - echo "" - echo -e "${CGreen}Launching the Setup Menu in T-5 sec...${CClear}" - spinner 5 - vsetup - echo -e "${CClear}" - exit 0 - fi - fi - -##----------------------------------------## -## Modified by Martinski W. [2024-Nov-03] ## -##----------------------------------------## -# ------------------------------------------------------------------------------------------------------------------------- -# Main RTRMON program initialization -# ------------------------------------------------------------------------------------------------------------------------- - _IgnoreKeypresses_ ON - # Display the logo and indicator that stats are being gathered. - - clear - logoNM - echo -e "\r${CGreen} [Initiating Boot Sequence - Gathering Initial Stats...]" - echo "" - INITIALBOOT=1 - trimlogs - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: RTRMON is initializing for the first time..." >> $LOGFILE - - # Capture initial traffic and store current WAN/WiFi bytes stats - if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then - if [ $WANOverride == "Auto" ]; then WANIFNAME=$(get_wan_setting ifname); else WANIFNAME=$WANOverride; fi - if [ -z $WANIFNAME ]; then WANIFNAME="eth0"; fi - oldwanrxbytes="$(cat /sys/class/net/$WANIFNAME/statistics/rx_bytes)" - oldwantxbytes="$(cat /sys/class/net/$WANIFNAME/statistics/tx_bytes)" - fi - - if [ "$FourBandCustom55624" == "True" ]; then - ifname5=$($timeoutcmd$timeoutsec nvram get wl0_ifname) - ifname52=$($timeoutcmd$timeoutsec nvram get wl1_ifname) - ifname6=$($timeoutcmd$timeoutsec nvram get wl2_ifname) - ifname24=$($timeoutcmd$timeoutsec nvram get wl3_ifname) - elif [ "$FourBandCustom56624" == "True" ]; then - ifname5=$($timeoutcmd$timeoutsec nvram get wl0_ifname) - ifname6=$($timeoutcmd$timeoutsec nvram get wl1_ifname) - ifname62=$($timeoutcmd$timeoutsec nvram get wl2_ifname) - ifname24=$($timeoutcmd$timeoutsec nvram get wl3_ifname) - elif [ "$ThreeBand2456" == "True" ]; then - ifname24=$($timeoutcmd$timeoutsec nvram get wl0_ifname) - ifname5=$($timeoutcmd$timeoutsec nvram get wl1_ifname) - ifname6=$($timeoutcmd$timeoutsec nvram get wl2_ifname) - elif [ "$ThreeBand2455" == "True" ]; then - ifname24=$($timeoutcmd$timeoutsec nvram get wl0_ifname) - ifname5=$($timeoutcmd$timeoutsec nvram get wl1_ifname) - ifname52=$($timeoutcmd$timeoutsec nvram get wl2_ifname) - else - ifname24=$($timeoutcmd$timeoutsec nvram get wl0_ifname) - ifname5=$($timeoutcmd$timeoutsec nvram get wl1_ifname) - fi - - old24rxbytes="$(cat /sys/class/net/$ifname24/statistics/rx_bytes)" - old24txbytes="$(cat /sys/class/net/$ifname24/statistics/tx_bytes)" - old5rxbytes="$(cat /sys/class/net/$ifname5/statistics/rx_bytes)" - old5txbytes="$(cat /sys/class/net/$ifname5/statistics/tx_bytes)" - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then - old52rxbytes="$(cat /sys/class/net/$ifname52/statistics/rx_bytes)" - old52txbytes="$(cat /sys/class/net/$ifname52/statistics/tx_bytes)" - fi - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then - old6rxbytes="$(cat /sys/class/net/$ifname6/statistics/rx_bytes)" - old6txbytes="$(cat /sys/class/net/$ifname6/statistics/tx_bytes)" - fi - if [ "$FourBandCustom56624" == "True" ]; then - old62rxbytes="$(cat /sys/class/net/$ifname62/statistics/rx_bytes)" - old62txbytes="$(cat /sys/class/net/$ifname62/statistics/tx_bytes)" - fi - oldlanrxbytes="$(cat /sys/class/net/br0/statistics/rx_bytes)" - oldlantxbytes="$(cat /sys/class/net/br0/statistics/tx_bytes)" - - #Get the Initial VPN stats - GetVPNWGIPCITY - GetVPNWGStats - - # Get initial TOP stats to average across the interval period - RM_ELAPSED_TIME=0 - RM_START_TIME="$(date +%s)" - - ##----------------------------------------## - ## Modified by Martinski W. [2024-Nov-04] ## - ##----------------------------------------## - timer=0 - lastTimerSec=0 - updateTimer=true - savedInterval="$Interval" - Interval="$bootInterval" - - # Initial Boot Sequence Loop # - while [ "$timer" -lt "$Interval" ] - do - if "$updateTimer" - then - updateTimer=false - timer="$((timer+1))" - lastTimerSec="$(date +%s)" - gettopstats "$timer" - fi - preparebar 53 "|" - progressbaroverride "$timer" "$Interval" "" "s" "Standard" - - ## Prevent repeatedly fast key presses from updating the timer ## - [ "$(date +%s)" -gt "$lastTimerSec" ] && updateTimer=true - done - - calculatestats - oldstats - - clear - INITIALBOOT=0 - Interval="$savedInterval" - -# ------------------------------------------------------------------------------------------------------------------------- -# Main loop that calls functions to perform all necessary calculations across the interval period -# ------------------------------------------------------------------------------------------------------------------------- -##----------------------------------------## -## Modified by Martinski W. [2024-Nov-03] ## -##----------------------------------------## -while true -do - - _SetUpTimeoutCmdVars_ - _SetLAN_HostName_ - _IgnoreKeypresses_ ON - - if [ "$NextPage" = "1" ]; then - DisplayPage1 - echo "" - elif [ "$NextPage" = "2" ]; then - DisplayPage2 - echo "" - elif [ "$NextPage" = "3" ]; then - DisplayPage3 - echo "" - elif [ "$NextPage" = "4" ]; then - DisplayPage4 - echo "" - elif [ "$NextPage" = "5" ]; then - DisplayPage5 - #echo "" - elif [ "$NextPage" = "6" ]; then - DisplayPage6 - #echo "" - elif [ "$NextPage" = "7" ]; then - DisplayPage7 - fi - - # Reset stats after the UI has finished drawing - memused1=0 - memfree1=0 - memshrd1=0 - membuff1=0 - memcach1=0 - memused2=0 - memfree2=0 - memshrd2=0 - membuff2=0 - memcach2=0 - cpuusr1=0 - cpusys1=0 - cpunice1=0 - cpuidle1=0 - displaycpuusr1=0 - displaycpusys1=0 - displaycpunice1=0 - displaycpuidle1=0 - displaycpuirq1=0 - - # Get fresh WAN stats - if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then - oldwanrxbytes="$(cat /sys/class/net/$WANIFNAME/statistics/rx_bytes)" - oldwantxbytes="$(cat /sys/class/net/$WANIFNAME/statistics/tx_bytes)" - fi - old24rxbytes="$(cat /sys/class/net/$ifname24/statistics/rx_bytes)" - old24txbytes="$(cat /sys/class/net/$ifname24/statistics/tx_bytes)" - old5rxbytes="$(cat /sys/class/net/$ifname5/statistics/rx_bytes)" - old5txbytes="$(cat /sys/class/net/$ifname5/statistics/tx_bytes)" - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then - old52rxbytes="$(cat /sys/class/net/$ifname52/statistics/rx_bytes)" - old52txbytes="$(cat /sys/class/net/$ifname52/statistics/tx_bytes)" - fi - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then - old6rxbytes="$(cat /sys/class/net/$ifname6/statistics/rx_bytes)" - old6txbytes="$(cat /sys/class/net/$ifname6/statistics/tx_bytes)" - fi - if [ "$FourBandCustom56624" == "True" ]; then - old62rxbytes="$(cat /sys/class/net/$ifname62/statistics/rx_bytes)" - old62txbytes="$(cat /sys/class/net/$ifname62/statistics/tx_bytes)" - fi - oldlanrxbytes="$(cat /sys/class/net/br0/statistics/rx_bytes)" - oldlantxbytes="$(cat /sys/class/net/br0/statistics/tx_bytes)" - - # Get fresh VPN stats - echo "" - GetVPNWGIPCITY loop - GetVPNWGStats - - printf "${CGreen}\r " - printf "${CGreen}\r" - - - # Run through the stats gathering loop based on the current interval - RM_ELAPSED_TIME=0 - RM_START_TIME="$(date +%s)" - - ##----------------------------------------## - ## Modified by Martinski W. [2024-Nov-05] ## - ##----------------------------------------## - timer=0 - lastTimerSec=0 - updateTimer=true - pausedTimerEnabled=false - pausedTimerDispStr="" - - # Main Loop # - while [ "$timer" -lt "$Interval" ] - do - if "$updateTimer" - then - updateTimer=false - timer="$((timer+1))" - lastTimerSec="$(date +%s)" - gettopstats "$timer" - fi - preparebar 46 "|" - progressbaroverride "$timer" "$Interval" "" "s" "Standard" - if [ "$timerReset" = "1" ] ; then timer="$Interval" ; fi - - ## Prevent repeatedly fast key presses from updating the timer ## - [ "$(date +%s)" -gt "$lastTimerSec" ] && updateTimer=true - done - - # Do a fresh round of stats and save them to the old stats for display purposes - calculatestats - oldstats - clear - - if [ "$autorotate" = "1" ] && [ "$timer" -ge "$Interval" ] - then - if [ "$NextPage" = "1" ]; then NextPage=2 #DisplayPage2# - elif [ "$NextPage" = "2" ]; then NextPage=3 #DisplayPage3# - elif [ "$NextPage" = "3" ]; then NextPage=4 #DisplayPage4# - elif [ "$NextPage" = "4" ]; then NextPage=5 #DisplayPage5# - elif [ "$NextPage" = "5" ]; then NextPage=6 #DisplayPage6# - elif [ "$NextPage" = "6" ]; then NextPage=7 #DisplayPage7# - elif [ "$NextPage" = "7" ]; then NextPage=1 #DisplayPage1# - fi - fi - - prevHideOpts=X - prevSortByOpt=X -done - -_IgnoreKeypresses_ OFF - -exit 0 - -} #2>&1 | tee $LOG | logger -t $(basename $0)[$$] # uncomment/comment to enable/disable debug mode From e0ea3c767092a321a181cfb26ca67862b55809da Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Thu, 4 Dec 2025 19:23:51 -0500 Subject: [PATCH 05/62] Update version.txt --- version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.txt b/version.txt index 5859406..530cdd9 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -2.2.3 +2.2.4 From cc8d269895d9db49be9855113bc79ab3760ae408 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Thu, 4 Dec 2025 21:58:13 -0500 Subject: [PATCH 06/62] Update rtrmon.sh --- rtrmon.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rtrmon.sh b/rtrmon.sh index fdb7cae..166c275 100644 --- a/rtrmon.sh +++ b/rtrmon.sh @@ -2008,8 +2008,10 @@ calculatestats() # CPU - Temp - borrowed from @Maverickcdn - thank you! if [ -f /sys/class/thermal/thermal_zone0/temp ]; then F_cputemp=$($timeoutcmd$timeoutsec cat /sys/class/thermal/thermal_zone0/temp | cut -c -2) - elif [ -f /proc/dmu/temperature ]; then # Thanks to PeterR for the bug report on AC68U's - hopefully this will fix that + elif [ -f /proc/dmu/temperature ]; then # Thanks to PeterR for the bug report on AC68U's F_cputemp=$($timeoutcmd$timeoutsec cat /proc/dmu/temperature | cut -c19-20) + elif [ -f /sys/power/bpcm/cpu_temp ]; then # Thanks to fr0s7 for the bug report and Dave14305 for finding the needle in the haystack! + F_cputemp=$($timeoutcmd$timeoutsec cat /sys/power/bpcm/cpu_temp | cut -d' ' -f2 | cut -d'.' -f1) fi # Memory - Usage From e71c8f6cc5ab69f4f6cbe254d2d9bc679e45c974 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Thu, 4 Dec 2025 21:58:44 -0500 Subject: [PATCH 07/62] Create rtrmon-2.2.3.sh --- rtrmon-2.2.3.sh | 6632 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 6632 insertions(+) create mode 100644 rtrmon-2.2.3.sh diff --git a/rtrmon-2.2.3.sh b/rtrmon-2.2.3.sh new file mode 100644 index 0000000..6ad5bd5 --- /dev/null +++ b/rtrmon-2.2.3.sh @@ -0,0 +1,6632 @@ +#!/bin/sh + +# RTRMON - Asus-Merlin Router Monitor by Viktor Jaep, 2022-2025 +# +# RTRMON is a shell script that provides near-realtime stats about your Asus-Merlin firmware router. Instead of having to +# find this information on various different screens or apps, this tool was built to bring all this info together in one +# stat dashboard. Having a 'system' dashboard showing current CPU, Memory, Disk and Network stats would compiment other +# dashboard-like scripts greatly (like RTRMON), sitting side-by-side in their own SSH windows to give you everything +# you need to know that's happening on your network with a glance at your screen. +# +# Capabilities have been added to give a full view of your router's CPU, Memory, Disk, NVRAM, Swap file, WAN, LAN, Wi-FI, +# IP4/6 addresses, CPU/Antenna Temps, in addition to having incorporated the Ookla Speedtest Binaries for you to run an on +# -demand Speedtest with the press of a button. New supported models are continually being added as @RMerlin adds support +# for them with his own firmware. +# +# Please use the 'sh rtrmon.sh -setup' command to configure the necessary parameters that match your environment the best! +# +# Last Modified: 2025-Nov-16 +########################################################################################################################### + +#Preferred standard router binaries path +export PATH="/sbin:/bin:/usr/sbin:/usr/bin:$PATH" + +# ------------------------------------------------------------------------------------------------------------------------- +# System Variables (Do not change beyond this point or this may change the programs ability to function correctly) +# ------------------------------------------------------------------------------------------------------------------------- +Version="2.2.3" +Beta=0 +ScreenshotMode=0 +LOGFILE="/jffs/addons/rtrmon.d/rtrmon.log" # Logfile path/name that captures important date/time events - change +APPPATH="/jffs/scripts/rtrmon.sh" # Path to the location of rtrmon.sh +CFGPATH="/jffs/addons/rtrmon.d/rtrmon.cfg" # Path to the location of rtrmon.cfg +DLVERPATH="/jffs/addons/rtrmon.d/version.txt" # Path to downloaded version from the source repository +OOKLAPATH="/jffs/addons/rtrmon.d/speedtest" # Path to Ookla speedtest binary +SPDRESPATH="/jffs/addons/rtrmon.d/results.txt" # Path to latest speedtest results +IFLIST="/jffs/addons/rtrmon.d/interfaces.txt" # Path to the Interface List +DIAGRESPATH="/jffs/addons/rtrmon.d/diagres.txt" # Path to the network diagnostics results +NMAPWANRESPATH="/jffs/addons/rtrmon.d/nwanres.txt" # Path to the nmap WAN open TCP port results +NMAPLANRESPATH="/jffs/addons/rtrmon.d/nlanres.txt" # Path to the nmap LAN open TCP port results +NMAPUWANRESPATH="/jffs/addons/rtrmon.d/nuwanres.txt" # Path to the nmap WAN open UDP port results +NMAPULANRESPATH="/jffs/addons/rtrmon.d/nulanres.txt" # Path to the nmap LAN open UDP port results +INITIALBOOT=0 +CHANGES=0 +LOGSIZE=2000 +Interval=10 +MaxSpeedInet=1000 +MaxSpeedInetUL=50 +MaxSpeedLAN=1000 +MaxSpeed24Ghz=450 +MaxSpeed5Ghz=780 +MaxSpeed6Ghz=920 +TempUnits="C" +Speedtst=0 +WANOverride="Auto" +WAN0AltModes=0 +VPNSite2Site=0 +PSView="TCP" +NCView="WAN" +spdtestsvrID=0 +autorotate=0 +autorotateindicator="OFF" +QueueSpdTest=0 +QueueNetworkDiag=0 +QueueNetworkConn=0 +QueueVPNSlot1=0 +QueueVPNSlot2=0 +QueueVPNSlot3=0 +QueueVPNSlot4=0 +QueueVPNSlot5=0 +QueueWGSlot1=0 +QueueWGSlot2=0 +QueueWGSlot3=0 +QueueWGSlot4=0 +QueueWGSlot5=0 +vpn1slot=0 +vpn2slot=0 +vpn3slot=0 +vpn4slot=0 +vpn5slot=0 +VPNState=0 +VPN2State=0 +VPN3State=0 +VPN4State=0 +VPN5State=0 +vpn1city="Unknown" +vpn2city="Unknown" +vpn3city="Unknown" +vpn4city="Unknown" +vpn5city="Unknown" +vpn1ip="0.0.0.0" +vpn2ip="0.0.0.0" +vpn3ip="0.0.0.0" +vpn4ip="0.0.0.0" +vpn5ip="0.0.0.0" +vpn1on="False" +vpn2on="False" +vpn3on="False" +vpn4on="False" +vpn5on="False" +wg1on="False" +wg2on="False" +wg3on="False" +wg4on="False" +wg5on="False" +FromUI=0 +NextPage=1 +memused1=0 +memfree1=0 +memshrd1=0 +membuff1=0 +memcach1=0 +memused2=0 +memfree2=0 +memshrd2=0 +membuff2=0 +memcach2=0 +cpuusr1=0 +cpusys1=0 +cpunice1=0 +cpuidle1=0 +cpuirq1=0 +displaycpuusr1=0 +displaycpusys1=0 +displaycpunice1=0 +displaycpuidle1=0 +displaycpuirq1=0 +w24udsched="Scheduler Inactive" +w5udsched="Scheduler Inactive" +w52udsched="Scheduler Inactive" +w6udsched="Scheduler Inactive" +w62udsched="Scheduler Inactive" +w24updown="UP" +w5updown="UP" +w52updown="UP" +w6updown="UP" +w62updown="UP" +SortbyOpt="Name" + +##-------------------------------------## +## Added by Martinski W. [2024-Nov-04] ## +##-------------------------------------## +timerReset=0 +timeoutcmd="" # For "timeout" cmd for "nvram" calls # +timeoutsec="" # For "timeout" cmd for "nvram" calls # +timeoutlng="" # For "timeout" cmd for "nvram" calls # +hideoptions=1 # Hide/Show menu options flag # +prevHideOpts=X # Avoid redisplaying the options menu unnecessarily too often # +prevSortByOpt=X # Avoid resetting the timer loop unnecessarily too often # +bootInterval=10 # For "Boot Sequence" loop # +LAN_HostName="" +readonly gSavedSTTY="$(stty -g)" + +##-------------------------------------## +## Added by Martinski W. [2024-Nov-05] ## +##-------------------------------------## +pausedTimerEnabled=false # To pause/resume main loop timer cycle # +pausedTimerDispStr="" +readonly pausedTimerMsgStr=" [** PAUSED **] " +readonly pausedTimerMsgLen="${#pausedTimerMsgStr}" + +# Color variables +CBlack="\e[1;30m" +InvBlack="\e[1;40m" +CRed="\e[1;31m" +InvRed="\e[1;41m" +CGreen="\e[1;32m" +InvGreen="\e[1;42m" +CDkGray="\e[1;90m" +InvDkGray="\e[1;100m" +InvLtGray="\e[1;47m" +CYellow="\e[1;33m" +InvYellow="\e[1;43m" +CBlue="\e[1;34m" +InvBlue="\e[1;44m" +CMagenta="\e[1;35m" +CCyan="\e[1;36m" +InvCyan="\e[1;46m" +CWhite="\e[1;37m" +InvWhite="\e[1;107m" +CClear="\e[0m" + +# ------------------------------------------------------------------------------------------------------------------------- +# Functions +# ------------------------------------------------------------------------------------------------------------------------- + +#Shows the version bar formatted for build and date/time with TZ spacing# +##----------------------------------------## +## Modified by Martinski W. [2024-Nov-04] ## +##----------------------------------------## +showheader() +{ + if [ "$hideoptions" = "0" ] && [ "$hideoptions" != "$prevHideOpts" ] + then displayopsmenu ; fi + + timerReset=0 + prevHideOpts="$hideoptions" + prevSortByOpt="$SortbyOpt" + + tzone="$(date +%Z)" + tzonechars="${#tzone}" + + if [ "$tzonechars" = "1" ]; then tzspaces=" "; + elif [ "$tzonechars" = "2" ]; then tzspaces=" "; + elif [ "$tzonechars" = "3" ]; then tzspaces=" "; + elif [ "$tzonechars" = "4" ]; then tzspaces=" "; + elif [ "$tzonechars" = "5" ]; then tzspaces=" "; fi + + #Display RTRMON client header + echo -en "${InvGreen} ${InvDkGray}${CWhite} RTRMON - v" + printf "%-8s" $Version + echo -e " ${CGreen}(S)${CWhite}how/${CGreen}(H)${CWhite}ide Operations Menu ${InvDkGray} $tzspaces$(date) ${CClear}" +} + +# ------------------------------------------------------------------------------------------------------------------------- +# Displays the "Operations Menu" on top of screen. + +##----------------------------------------## +## Modified by Martinski W. [2024-Nov-02] ## +##----------------------------------------## +displayopsmenu() +{ + amtmdisp="${CDkGray}[n/a] " + + echo -e "${InvGreen} ${InvDkGray}${CWhite} Operations Menu ${CClear}" + if [ "$vpn1on" == "True" ] || [ "$vpn2on" == "True" ] || [ "$vpn3on" == "True" ] || [ "$vpn4on" == "True" ] || [ "$vpn5on" == "True" ] + then + echo -e "${InvGreen} ${CClear} Speedtest ${CGreen}(I)${CClear} WAN / VPN 1:${CGreen}(1)${CClear} 2:${CGreen}(2)${CClear} 3:${CGreen}(3)${CClear} 4:${CGreen}(4)${CClear} 5:${CGreen}(5)${CClear} ${InvGreen} ${CClear} ${CGreen}(M)${CClear}ain Setup Menu / Configuration Menu${CClear}" + else + echo -e "${InvGreen} ${CClear} Speedtest ${CGreen}(I)${CClear} WAN ${CDkGray}/ VPN 1:(1) 2:(2) 3:(3) 4:(4) 5:(5)${CClear} ${InvGreen} ${CClear} ${CGreen}(M)${CClear}ain Setup Menu / Configuration Menu${CClear}" + fi + if [ "$wg1on" == "True" ] || [ "$wg2on" == "True" ] || [ "$wg3on" == "True" ] || [ "$wg4on" == "True" ] || [ "$wg5on" == "True" ] + then + echo -e "${InvGreen} ${CClear} Speedtest Wireguard 1:${CGreen}(6)${CClear} 2:${CGreen}(7)${CClear} 3:${CGreen}(8)${CClear} 4:${CGreen}(9)${CClear} 5:${CGreen}(0)${CClear} ${InvGreen} ${CClear} L${CGreen}(O)${CClear}g Viewer / Trim Log Size (rows): ${CGreen}$LOGSIZE${CClear}" + else + echo -e "${InvGreen} ${CClear} ${CDkGray}Speedtest Wireguard 1:(6) 2:(7) 3:(8) 4:(9) 5:(0)${CClear} ${InvGreen} ${CClear} L${CGreen}(O)${CClear}g Viewer / Trim Log Size (rows): ${CGreen}$LOGSIZE${CClear}" + fi + echo -e "${InvGreen} ${CClear} Run Router Network ${CGreen}(D)${CClear}iagnostics ${InvGreen} ${CClear} ${CGreen}(N)${CClear}ext Page / ${CGreen}(P)${CClear}revious Page: ${CGreen}($NextPage/7)${CClear}" + echo -e "${InvGreen} ${CClear} Refresh ${CGreen}(C)${CClear}urrent Network Statistics ${InvGreen} ${CClear} Auto ${CGreen}(R)${CClear}otate Pages Option: ${CGreen}$autorotateindicator${CClear}" + echo -e "${InvGreen} ${CClear} View ${CGreen}(W)${CClear}AN / ${CGreen}(L)${CClear}AN / ${CGreen}(V)${CClear}PN / W${CGreen}(G)${CClear} Stats ${InvGreen} ${CClear} Router Model/FW: ${CGreen}${RouterModel} | ${FWBUILD}${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo "" +} + +##-------------------------------------## +## Added by Martinski W. [2024-Nov-02] ## +##-------------------------------------## +_ConsumeKeypressBuffer_() +{ + local savedSettings + local keyPress='' prevTimeSec + savedSettings="$(stty -g)" + prevTimeSec="$(date +%s)" + read -rs -n1000 -t 1 keyPress < "$(tty 0>&2)" + while [ "$(date +%s)" -lt "$((prevTimeSec + 1))" ] + do + stty -echo -icanon min 0 time 1 + cat - > /dev/null + done + stty "$savedSettings" +} + +##-------------------------------------## +## Added by Martinski W. [2024-Nov-02] ## +##-------------------------------------## +_IgnoreKeypresses_() +{ + if [ $# -eq 0 ] || [ -z "$1" ] + then return 1 ; fi + case "$1" in + ON) stty -echo ;; + OFF) stty "$gSavedSTTY" ; stty echo ;; + esac +} + +# ------------------------------------------------------------------------------------------------------------------------- +# LogoNM displays the RTRMON script name in a cool ASCII font that fades in +##----------------------------------------## +## Modified by Martinski W. [2024-Nov-02] ## +##----------------------------------------## +logoNM () +{ + clear + echo "" + echo "" + echo "" + echo -e "${CDkGray} ____ __________ __ _______ _ __" + echo -e " / __ \/_ __/ __ \/ |/ / __ \/ | / /" + echo -e " / /_/ / / / / /_/ / /|_/ / / / / |/ /" + echo -e " / _, _/ / / / _, _/ / / / /_/ / /| /" + echo -e " /_/ |_| /_/ /_/ |_/_/ /_/\____/_/ |_/ v$Version" + echo "" + echo "" + printf "\r ${CGreen} [ INITIALIZING ] ${CClear}" + _ConsumeKeypressBuffer_ + clear + echo "" + echo "" + echo "" + echo -e "${CYellow} ____ __________ __ _______ _ __" + echo -e " / __ \/_ __/ __ \/ |/ / __ \/ | / /" + echo -e " / /_/ / / / / /_/ / /|_/ / / / / |/ /" + echo -e " / _, _/ / / / _, _/ / / / /_/ / /| /" + echo -e " /_/ |_| /_/ /_/ |_/_/ /_/\____/_/ |_/ v$Version" + echo "" + echo "" +} + +# ------------------------------------------------------------------------------------------------------------------------- +# logoNMexit displays the RTRMON script name in a cool ASCII font that fades out + +logoNMexit () { + clear + echo "" + echo "" + echo "" + echo -e "${CYellow} ____ __________ __ _______ _ __" + echo -e " / __ \/_ __/ __ \/ |/ / __ \/ | / /" + echo -e " / /_/ / / / / /_/ / /|_/ / / / / |/ /" + echo -e " / _, _/ / / / _, _/ / / / /_/ / /| /" + echo -e " /_/ |_| /_/ /_/ |_/_/ /_/\____/_/ |_/ v$Version" + echo "" + echo "" + printf "\r ${CGreen} [ SHUTTING DOWN ] ${CClear}" + sleep 1 + clear + echo "" + echo "" + echo "" + echo -e "${CDkGray} ____ __________ __ _______ _ __" + echo -e " / __ \/_ __/ __ \/ |/ / __ \/ | / /" + echo -e " / /_/ / / / / /_/ / /|_/ / / / / |/ /" + echo -e " / _, _/ / / / _, _/ / / / /_/ / /| /" + echo -e " /_/ |_| /_/ /_/ |_/_/ /_/\____/_/ |_/ v$Version" + echo "" + echo "" + printf "\r ${CGreen} [ SHUTTING DOWN ] ${CClear}" + sleep 1 + printf "\r ${CDkGray} [ GOODBYE... ] ${CClear}\n\n" + sleep 1 +} + +##-------------------------------------## +## Added by Martinski W. [2024-Nov-02] ## +##-------------------------------------## +_PressAnyKeyToContinue_() +{ printf "\nPress any key to continue..." ; read -rsn1 anykey ; echo ; } + +# ------------------------------------------------------------------------------------------------------------------------- +# promptyn takes input for Y/N questions + +promptyn () { # No defaults, just y or n + while true; do + read -p '[y/n]? ' YESNO + case "$YESNO" in + [Yy]* ) return 0 ;; + [Nn]* ) return 1 ;; + * ) echo -e "\nPlease answer y or n.";; + esac + done +} + +# ------------------------------------------------------------------------------------------------------------------------- +# Spinner provides a small spinning indicator on the screen to show script activity + +spinner() +{ + spins="$1" + + spin=0 + totalspins="$((spins / 4))" + while [ "$spin" -le "$totalspins" ] + do + for spinchar in / - \\ \| + do + printf "\r$spinchar" + sleep 1 + done + spin="$((spin+1))" + done + + printf "\r" +} + +# ------------------------------------------------------------------------------------------------------------------------- +# Preparebar and Progressbar is a script that provides a nice progressbar to show script activity and bar charts +##----------------------------------------## +## Modified by Martinski W. [2024-Nov-02] ## +##----------------------------------------## +preparebar() +{ + # $1 - bar length + # $2 - bar char + barlen="$1" + barspaces="$(printf "%*s" "$1" ' ')" + barchars="$(printf "%*s" "$1" ' ' | tr ' ' "$2")" +} + +##----------------------------------------## +## Modified by Martinski W. [2024-Nov-02] ## +##----------------------------------------## +# Had to make some mods to the variables being passed, and created an inverse colored progress bar +progressbar() +{ + # $1 - number (-1 for clearing the bar) + # $2 - max number + # $3 - system name + # $4 - measurement + # $5 - standard/reverse progressbar + # $6 - alternate display values + # $7 - alternate value for progressbar exceeding 100% + + insertspc=" " + + if [ "$1" -eq -1 ] + then + printf "\r $barspaces\r" + else + if [ $# -gt 6 ] && [ -n "$7" ] && [ "$1" -ge "$7" ] + then + barch="$(($7*barlen/$2))" + barsp="$((barlen-barch))" + progr="$((100*$1/$2))" + else + barch="$(($1*barlen/$2))" + barsp="$((barlen-barch))" + progr="$((100*$1/$2))" + fi + + if [ $# -gt 5 ] && [ -n "$6" ]; then AltNum="$6" ; else AltNum="$1" ; fi + + if [ "$5" = "Standard" ] + then + if [ "$progr" -le 60 ]; then + printf "${InvGreen}${CWhite}$insertspc${CClear}${CWhite}${3} ${CDkGray}[${CGreen}%.${barch}s%.${barsp}s${CDkGray}]${CClear} ${CWhite}${InvDkGray}$AltNum ${4} / ${progr}%%\r${CClear}" "$barchars" "$barspaces" + elif [ "$progr" -gt 60 ] && [ "$progr" -le 85 ]; then + printf "${InvYellow}${CBlack}$insertspc${CClear}${CYellow}${3} ${CDkGray}[${CYellow}%.${barch}s%.${barsp}s${CDkGray}]${CClear} ${CWhite}${InvDkGray}$AltNum ${4} / ${progr}%%\r${CClear}" "$barchars" "$barspaces" + else + printf "${InvRed}${CWhite}$insertspc${CClear}${CRed}${3} ${CDkGray}[${CRed}%.${barch}s%.${barsp}s${CDkGray}]${CClear} ${CWhite}${InvDkGray}$AltNum ${4} / ${progr}%%\r${CClear}" "$barchars" "$barspaces" + fi + elif [ "$5" = "Reverse" ] + then + if [ "$progr" -le 15 ]; then + printf "${InvRed}${CWhite}$insertspc${CClear}${CRed}${3} ${CDkGray}[${CRed}%.${barch}s%.${barsp}s${CDkGray}]${CClear} ${CWhite}${InvDkGray}$AltNum ${4} / ${progr}%%\r${CClear}" "$barchars" "$barspaces" + elif [ "$progr" -gt 15 ] && [ "$progr" -le 40 ]; then + printf "${InvYellow}${CBlack}$insertspc${CClear}${CYellow}${3} ${CDkGray}[${CYellow}%.${barch}s%.${barsp}s${CDkGray}]${CClear} ${CWhite}${InvDkGray}$AltNum ${4} / ${progr}%%\r${CClear}" "$barchars" "$barspaces" + else + printf "${InvGreen}${CWhite}$insertspc${CClear}${CWhite}${3}${CGreen} ${CDkGray}[${CGreen}%.${barch}s%.${barsp}s${CDkGray}]${CClear} ${CWhite}${InvDkGray}$AltNum ${4} / ${progr}%%\r${CClear}" "$barchars" "$barspaces" + fi + elif [ "$5" = "CPU" ] + then + if [ "$progr" -le 80 ]; then + printf "${InvGreen}${CWhite}$insertspc${CClear}${CWhite}${3}${CGreen} ${CDkGray}[${CGreen}%.${barch}s%.${barsp}s${CDkGray}]${CClear} ${CWhite}${InvDkGray}$AltNum ${4} / ${progr}%%\r${CClear}" "$barchars" "$barspaces" + elif [ "$progr" -gt 80 ] && [ "$progr" -le 90 ]; then + printf "${InvYellow}${CBlack}$insertspc${CClear}${CYellow}${3} ${CDkGray}[${CYellow}%.${barch}s%.${barsp}s${CDkGray}]${CClear} ${CWhite}${InvDkGray}$AltNum ${4} / ${progr}%%\r${CClear}" "$barchars" "$barspaces" + else + printf "${InvRed}${CWhite}$insertspc${CClear}${CRed}${3} ${CDkGray}[${CRed}%.${barch}s%.${barsp}s${CDkGray}]${CClear} ${CWhite}${InvDkGray}$AltNum ${4} / ${progr}%%\r${CClear}" "$barchars" "$barspaces" + fi + fi + fi +} + +# ------------------------------------------------------------------------------------------------------------------------- +# Shows a more minimalistic progress bar that indicates seconds/% +##----------------------------------------## +## Modified by Martinski W. [2024-Nov-06] ## +##----------------------------------------## +progressbaroverride() +{ + # $1 - number (-1 for clearing the bar) + # $2 - max number + # $3 - system name + # $4 - measurement + # $5 - standard/reverse progressbar + # $6 - alternate display values + # $7 - alternate value for progressbar exceeding 100% + + local barch barsp percnt altNum readTimeSec + insertspc=" " + + _GetPercent_() { printf "%.1f" "$(echo "$1" | awk "{print $1}")" ; } + + _UpdateProgressBar_() + { + if [ "$2" = "Standard" ] && [ "$INITIALBOOT" -eq 0 ] + then + printf " ${CWhite}${InvDkGray}%3d${1} /%5.1f%%${CClear} [${CGreen}e${CClear}=Exit] [Selection? ${InvGreen} ${CClear}${CGreen}] ${pausedTimerDispStr} \r${CClear}" "$altNum" "$percnt" + elif [ "$2" = "Standard" ] && [ "$INITIALBOOT" -eq 1 ] + then + printf "${CDkGray} [${CGreen}%.${barch}s%.${barsp}s${CDkGray}] \r${CClear}" "$barchars" "$barspaces" + fi + } + + _PausedTimerHandler_() + { + local keyPress readTimeSec + while "$pausedTimerEnabled" + do + keyPress='' + readTimeSec="$(date +%s)" + read -rsn1 -t 1 keyPress < "$(tty 0>&2)" + if [ "$keyPress" = "X" ] + then + pausedTimerEnabled=false + pausedTimerDispStr="$(printf "%*s" "$pausedTimerMsgLen" ' ')" + break + fi + if [ "$(date +%s)" -lt "$((readTimeSec + 1))" ] + then + stty -icanon min 0 time 5 + cat - > /dev/null + fi + done + } + + if [ "$1" -eq -1 ] + then + printf "\r $barspaces\r" + else + if [ $# -gt 6 ] && [ -n "$7" ] && [ "$1" -ge "$7" ] + then + barch="$(($7*barlen/$2))" + barsp="$((barlen-barch))" + percnt="$(_GetPercent_ "(100*$1/$2)")" + else + barch="$(($1*barlen/$2))" + barsp="$((barlen-barch))" + percnt="$(_GetPercent_ "(100*$1/$2)")" + fi + + if [ $# -gt 5 ] && [ -n "$6" ]; then altNum="$6" ; else altNum="$1" ; fi + + _UpdateProgressBar_ "$4" "$5" + + if [ "$INITIALBOOT" = "0" ] + then + # Borrowed this wonderful keypress capturing mechanism from @Eibgrad... thank you! :) + readTimeSec="$(date +%s)" + key_press=''; read -rsn1 -t 1 key_press < "$(tty 0>&2)" + + if [ "$key_press" ] + then + case "$key_press" in + [Cc]) QueueNetworkConn=1 + echo -e "${CClear}[Queuing Network Connection Stats] "; + sleep 1; NextPage=6; timerReset=1 + ;; + [Dd]) QueueNetworkDiag=1 + echo -e "${CClear}[Queuing Network Diagnostics] "; + sleep 1; NextPage=5; timerReset=1 + ;; + [Ee]) clear; logoNMexit; echo -e "${CClear}"; exit 0 + ;; + [Gg]) NCView="WG"; NextPage=6; timerReset=1 + ;; + [Hh]) hideoptions=1 ; [ "$hideoptions" != "$prevHideOpts" ] && timerReset=1 + ;; + [Ii]) QueueSpdTest=1 + echo -e "${CClear}[Queuing WAN Speedtest] "; + sleep 1; NextPage=4; timerReset=1 + ;; + [Ll]) NCView="LAN"; NextPage=6; timerReset=1 + ;; + [Mm]) _IgnoreKeypresses_ OFF + FromUI=1; vsetup; source "$CFGPATH" + echo -e "\n${CClear}[Returning to the Main UI momentarily] "; + sleep 1; FromUI=0; timerReset=1 + ;; + [Nn]) timerReset=1 + if [ "$NextPage" = "1" ]; then NextPage=2 + elif [ "$NextPage" = "2" ]; then NextPage=3 + elif [ "$NextPage" = "3" ]; then NextPage=4 + elif [ "$NextPage" = "4" ]; then NextPage=5 + elif [ "$NextPage" = "5" ]; then NextPage=6 + elif [ "$NextPage" = "6" ]; then NextPage=7 + elif [ "$NextPage" = "7" ]; then NextPage=1 + fi + ;; + [Oo]) _IgnoreKeypresses_ OFF ; vlogs ;; + [Pp]) timerReset=1 + if [ "$NextPage" = "1" ]; then NextPage=7 + elif [ "$NextPage" = "2" ]; then NextPage=1 + elif [ "$NextPage" = "3" ]; then NextPage=2 + elif [ "$NextPage" = "4" ]; then NextPage=3 + elif [ "$NextPage" = "5" ]; then NextPage=4 + elif [ "$NextPage" = "6" ]; then NextPage=5 + elif [ "$NextPage" = "7" ]; then NextPage=6 + fi + ;; + [Rr]) if [ "$autorotate" = 0 ] + then autorotate=1; autorotateindicator="ON" + elif [ "$autorotate" = "1" ] + then autorotate=0; autorotateindicator="OFF" + fi + timerReset=1 + ;; + [Ss]) hideoptions=0 ; [ "$hideoptions" != "$prevHideOpts" ] && timerReset=1 + ;; + [Tt]) PSView="TCP"; NextPage=5; timerReset=1 + ;; + [Uu]) PSView="UDP"; NextPage=5; timerReset=1 + ;; + [Vv]) NCView="VPN"; NextPage=6; timerReset=1 + ;; + [Ww]) NCView="WAN"; NextPage=6; timerReset=1 + ;; + X) if "$pausedTimerEnabled" + then + pausedTimerEnabled=false + pausedTimerDispStr="$(printf "%*s" "$pausedTimerMsgLen" ' ')" + else + pausedTimerEnabled=true + pausedTimerDispStr="${CWhite}${InvRed}${pausedTimerMsgStr}${CClear}" + _UpdateProgressBar_ "$4" "$5" + _PausedTimerHandler_ + fi + ;; + 1) QueueVPNSlot1=1 + echo -e "${CClear}[Queuing VPN1 Speedtest] "; + sleep 1; NextPage=4; timerReset=1 + ;; + 2) QueueVPNSlot2=1 + echo -e "${CClear}[Queuing VPN2 Speedtest] "; + sleep 1; NextPage=4; timerReset=1 + ;; + 3) QueueVPNSlot3=1 + echo -e "${CClear}[Queuing VPN3 Speedtest] "; + sleep 1; NextPage=4; timerReset=1 + ;; + 4) QueueVPNSlot4=1 + echo -e "${CClear}[Queuing VPN4 Speedtest] "; + sleep 1; NextPage=4; timerReset=1 + ;; + 5) QueueVPNSlot5=1 + echo -e "${CClear}[Queuing VPN5 Speedtest] "; + sleep 1; NextPage=4; timerReset=1 + ;; + 6) QueueWGSlot1=1 + echo -e "${CClear}[Queuing WG1 Speedtest] "; + sleep 1; NextPage=4; timerReset=1 + ;; + 7) QueueWGSlot2=1 + echo -e "${CClear}[Queuing WG2 Speedtest] "; + sleep 1; NextPage=4; timerReset=1 + ;; + 8) QueueWGSlot3=1 + echo -e "${CClear}[Queuing WG3 Speedtest] "; + sleep 1; NextPage=4; timerReset=1 + ;; + 9) QueueWGSlot4=1 + echo -e "${CClear}[Queuing WG4 Speedtest] "; + sleep 1; NextPage=4; timerReset=1 + ;; + 0) QueueWGSlot5=1 + echo -e "${CClear}[Queuing WG5 Speedtest] "; + sleep 1; NextPage=4; timerReset=1 + ;; + + [\!]) SortbyOpt="Name"; [ "$SortbyOpt" != "$prevSortByOpt" ] && [ "$NextPage" = "7" ] && timerReset=1 ;; + [\@]) SortbyOpt="IP"; [ "$SortbyOpt" != "$prevSortByOpt" ] && [ "$NextPage" = "7" ] && timerReset=1 ;; + [\#]) SortbyOpt="MAC"; [ "$SortbyOpt" != "$prevSortByOpt" ] && [ "$NextPage" = "7" ] && timerReset=1 ;; + *) ;; ##IGNORE INVALID key presses ## + esac + _IgnoreKeypresses_ ON + if [ "$(date +%s)" -lt "$((readTimeSec + 1))" ] + then + stty -icanon min 0 time 1 + cat - > /dev/null + fi + fi + else + ## Initial Boot Sequence Loop ## + _ConsumeKeypressBuffer_ + fi + fi +} + +# ------------------------------------------------------------------------------------------------------------------------- +# converttemps converts temp readouts from C to F or K + +converttemps () { +# $1 is the incoming C Temp + + if [ "$TempUnits" == "F" ]; then + currenttemp=$(awk -v v1=$1 'BEGIN{printf "%0.2f\n", (v1*9)/5+32}' | cut -d . -f 1) + currentrange=212 + elif [ "$TempUnits" == "K" ]; then + currenttemp=$(awk -v v1=$1 'BEGIN{printf "%0.2f\n", v1+273}' | cut -d . -f 1) + currentrange=373 + elif [ "$TempUnits" == "C" ]; then + currenttemp=$1 + currentrange=100 + else + # Default to C if someone entered something other than C, F or K + TempUnits="C" + currenttemp=$1 + currentrange=100 + fi + +} + +# ------------------------------------------------------------------------------------------------------------------------- +# updatecheck downloads the latest update version file from github, and compares it with what's currently installed + +updatecheck () { + + # Download the latest version file from the source repository + curl --silent --retry 3 "https://raw.githubusercontent.com/ViktorJp/RTRMON/master/version.txt" -o "/jffs/addons/rtrmon.d/version.txt" + + if [ -f $DLVERPATH ] + then + # Read in its contents for the current version file + DLVersion=$(cat $DLVERPATH) + + # Compare the new version with the old version and log it + if [ "$Beta" == "1" ]; then # Check if Dev/Beta Mode is enabled and disable notification message + UpdateNotify=0 + elif [ "$DLVersion" != "$Version" ]; then + DLVersionPF=$(printf "%-8s" $DLVersion) + VersionPF=$(printf "%-8s" $Version) + UpdateNotify="${InvYellow} ${InvDkGray}${CWhite} Update available: v$VersionPF -> v$DLVersionPF ${CClear}" + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new update (v$DLVersion) is available to download" >> $LOGFILE + else + UpdateNotify=0 + fi + fi +} + +# ------------------------------------------------------------------------------------------------------------------------- +# calls the nano text editor to view the RTRMON log file + +vlogs() { + +export TERM=linux +nano +999999 --linenumbers $LOGFILE +timerReset=1 + +} + +# ------------------------------------------------------------------------------------------------------------------------- +# trimlogs will cut down log size (in rows) based on custom value + +trimlogs() +{ + + if [ "$LOGSIZE" -gt 0 ] + then + currlogsize=$(wc -l $LOGFILE | awk '{ print $1 }' ) # Determine the number of rows in the log + + if [ "$currlogsize" -gt "$LOGSIZE" ] # If it's bigger than the max allowed, tail/trim it! + then + echo "$(tail -$LOGSIZE $LOGFILE)" > $LOGFILE + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: Trimmed the log file down to $LOGSIZE lines" >> $LOGFILE + fi + + fi +} + +# ------------------------------------------------------------------------------------------------------------------------- +# vconfig guides you through the various configuration options for RTRMON +##----------------------------------------## +## Modified by Martinski W. [2024-Nov-02] ## +##----------------------------------------## +vconfig() +{ + _SetUpTimeoutCmdVars_ + + if [ -f "$CFGPATH" ] #Making sure file exists before proceeding + then + source "$CFGPATH" + + CHANGES=0 #track notification to save your changes# + + while true + do + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} RTRMON Configuration Options ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please choose from the various options below, which allow you to modify certain${CClear}" + echo -e "${InvGreen} ${CClear} customizable parameters that affect the operation of this script.${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 1)${CClear} : Timer Interval (seconds) : ${CGreen}$Interval" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 2)${CClear} : Max Internet Download Speed (Mbps) : ${CGreen}$MaxSpeedInet" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 3)${CClear} : Max Internet Upload Speed (Mbps) : ${CGreen}$MaxSpeedInetUL" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 4)${CClear} : Max LAN Speed (Mbps) : ${CGreen}$MaxSpeedLAN" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 5)${CClear} : Max 2.4GHz Speed (Mbps) : ${CGreen}$MaxSpeed24Ghz" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 6)${CClear} : Max 5GHz Speed (Mbps) : ${CGreen}$MaxSpeed5Ghz" + + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 7)${CClear} : Max 6GHz Speed (Mbps) : ${CGreen}$MaxSpeed6Ghz" + else + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 7)${CClear} : ${CDkGray}Max 6GHz Speed (Mbps) : N/A" + fi + + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 8)${CClear} : Temperature Units (C/F/K) : ${CGreen}$TempUnits" + + echo -en "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 9)${CClear} : Enable Ookla Speedtest? (Y/N) : ${CGreen}" + if [ "$Speedtst" = "0" ] + then printf "No\n" + else printf "Yes\n" + fi + + if [ "$spdtestsvrID" == "0" ] && [ "$Speedtst" == "1" ]; then + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(10)${CClear} : Custom Speedtest Server ID? : ${CGreen}Use Closest" + elif [ "$spdtestsvrID" != "0" ] && [ "$Speedtst" == "1" ]; then + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(10)${CClear} : Custom Speedtest Server ID? : ${CGreen}$spdtestsvrID" + else + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(10)${CClear} : Custom Speedtest Server ID? : ${CDkGray}N/A" + fi + + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(11)${CClear} : WAN0 Interface Override? : ${CGreen}$WANOverride" + + if [ "$WAN0AltModes" == "0" ]; then WAN0AltModesdisp="No"; else WAN0AltModesdisp="Yes"; fi + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(12)${CClear} : Mark Router As iMesh Node/Repeater/Bridge? : ${CGreen}$WAN0AltModesdisp" + if [ "$VPNSite2Site" == "0" ]; then VPNSite2Sitedisp="No"; else VPNSite2Sitedisp="Yes"; fi + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(13)${CClear} : Mark Router As VPN Site-To-Site Only? : ${CGreen}$VPNSite2Sitedisp" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(14)${CClear} : Custom Event Log Size? : ${CGreen}$LOGSIZE" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite} | ${CClear}" + + if [ $CHANGES -eq 0 ]; then + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( s)${CClear} : Save Config & Exit" + else + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( s)${CClear} : Save Config & Exit ${CWhite}${InvRed}<-- Save your changes! ${CClear}" + fi + + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( e)${CClear} : Exit & Discard Changes" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + read -p "Please select? (1-14, s=Save, e=Exit): " ConfigSelection + CHANGES=1 + # Execute chosen selections + case "$ConfigSelection" in + + 1) # ----------------------------------------------------------------------------------------- + while true + do + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Refresh Interval ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please indicate after how many seconds you would like RTRMON to refresh your stats?${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} (Default = 10 seconds)${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo + echo -e "${CClear}Current Refresh Interval: ${CGreen}${Interval}${CClear} seconds" + echo + read -p "Please enter value in seconds [5-999] (e=Exit): " newInterval + if [ -z "$newInterval" ] || echo "$newInterval" | grep -qE "^(e|E)$" + then + if echo "$Interval" | grep -qE "^([1-9][0-9]{0,2})$" && \ + [ "$Interval" -ge 5 ] && [ "$Interval" -le 999 ] + then + timer="$Interval" + printf "\n${CClear}[Exiting]\n" + sleep 1 ; break + else + printf "\n${CRed}*ERROR*: Please enter a valid number between 5 and 999.${CClear}\n" + _PressAnyKeyToContinue_ + fi + elif echo "$newInterval" | grep -qE "^([1-9][0-9]{0,2})$" && \ + [ "$newInterval" -ge 5 ] && [ "$newInterval" -le 999 ] + then + Interval="$newInterval" + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new refresh interval ($Interval) has been selected." >> $LOGFILE + CHANGES=1 + timer="$Interval" + printf "\n${CClear}[OK]\n" + sleep 1 ; break + else + printf "\n${CRed}*ERROR*: Please enter a valid number between 5 and 999.${CClear}\n" + _PressAnyKeyToContinue_ + fi + done + ;; + + 2) # ----------------------------------------------------------------------------------------- + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Maximum Internet Download Bandwidth ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please indicate what your maximum internet download bandwidth/speed is in Mbps?${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} (Default = 50 Mbps)${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${CClear}Current: ${CGreen}$MaxSpeedInet${CClear} Mbps" + echo "" + read -p 'Please enter value in Mbps (ex: 1000): ' MaxSpeedInet1 + MaxSpeedInet2=$(echo $MaxSpeedInet1 | tr -d -c 0-9) + if [ -z "$MaxSpeedInet1" ]; then MaxSpeedInet=50; else MaxSpeedInet=$MaxSpeedInet2; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new Internet Download Bandwidth soeed ($MaxSpeedInet Mbps) has been selected." >> $LOGFILE + ;; + + 3) # ----------------------------------------------------------------------------------------- + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Maximum Internet Upload Bandwidth ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please indicate what your maximum internet upload bandwidth/speed is in Mbps?${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} (Default = 50 Mbps)${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${CClear}Current: ${CGreen}$MaxSpeedInetUL${CClear} Mbps" + echo "" + read -p 'Please enter value in Mbps (ex: 1000): ' MaxSpeedInetUL1 + MaxSpeedInetUL2=$(echo $MaxSpeedInetUL1 | tr -d -c 0-9) + if [ -z "$MaxSpeedInetUL1" ]; then MaxSpeedInetUL=50; else MaxSpeedInetUL=$MaxSpeedInetUL2; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new Internet Upload Bandwidth speed ($MaxSpeedInetUL Mbps) has been selected." >> $LOGFILE + ;; + + 4) # ----------------------------------------------------------------------------------------- + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Maximum Local Area Network (LAN) Bandwidth ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please indicate what your maximum LAN bandwidth/speed is in Mbps?${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} (Default = 1000 Mbps)${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${CClear}Current: ${CGreen}$MaxSpeedLAN${CClear} Mbps" + echo "" + read -p 'Please enter value in Mbps (ex: 1000): ' MaxSpeedLAN1 + MaxSpeedLAN2=$(echo $MaxSpeedLAN1 | tr -d -c 0-9) + if [ -z "$MaxSpeedLAN1" ]; then MaxSpeedLAN=1000; else MaxSpeedLAN=$MaxSpeedLAN2; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new LAN Bandwidth speed ($MaxSpeedLAN Mbps) has been selected." >> $LOGFILE + ;; + + 5) # ----------------------------------------------------------------------------------------- + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Maximum 2.4GHz Bandwidth Speed ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please indicate what your maximum realistic 2.4GHz speed is in Mbps?${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} (Default = 450 Mbps)${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${CClear}Current: ${CGreen}$MaxSpeed24Ghz${CClear} Mbps" + echo "" + read -p 'Please enter value in Mbps (ex: 1000): ' MaxSpeed24Ghz1 + MaxSpeed24Ghz2=$(echo $MaxSpeed24Ghz1 | tr -d -c 0-9) + if [ -z "$MaxSpeed24Ghz1" ]; then MaxSpeed24Ghz=450; else MaxSpeed24Ghz=$MaxSpeed24Ghz2; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new 2.4GHz Bandwidth speed ($MaxSpeed24Ghz Mbps) has been selected." >> $LOGFILE + ;; + + 6) # ----------------------------------------------------------------------------------------- + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Maximum 5GHz Bandwidth Speed ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please indicate what your maximum realistic 5GHz speed is in Mbps?${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} (Default = 780 Mbps)${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${CClear}Current: ${CGreen}$MaxSpeed5Ghz${CClear} Mbps" + echo "" + read -p 'Please enter value in Mbps (ex: 1000): ' MaxSpeed5Ghz1 + MaxSpeed5Ghz2=$(echo $MaxSpeed5Ghz1 | tr -d -c 0-9) + if [ -z "$MaxSpeed5Ghz1" ]; then MaxSpeed5Ghz=780; else MaxSpeed5Ghz=$MaxSpeed5Ghz2; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new 5GHz Bandwidth speed ($MaxSpeed5Ghz Mbps) has been selected." >> $LOGFILE + ;; + + 7) # ----------------------------------------------------------------------------------------- + clear + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then + echo -e "${InvGreen} ${InvDkGray}${CWhite} Maximum 6GHz Bandwidth Speed ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please indicate what your maximum realistic 6GHz speed is in Mbps?${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} (Default = 920 Mbps)${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${CClear}Current: ${CGreen}$MaxSpeed6Ghz${CClear} Mbps" + echo "" + read -p 'Please enter value in Mbps (ex: 1000): ' MaxSpeed6Ghz1 + MaxSpeed6Ghz2=$(echo $MaxSpeed6Ghz1 | tr -d -c 0-9) + if [ -z "$MaxSpeed6Ghz1" ]; then MaxSpeed6Ghz=920; else MaxSpeed6Ghz=$MaxSpeed6Ghz2; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new 6GHz Bandwidth speed ($MaxSpeed6Ghz Mbps) has been selected." >> $LOGFILE + else + echo -e "${CRed}This item is currently only available for router models:" + echo -e "GT-AXE11000, GT-AXE16000, RT-BE96U, RT-BE92U and GT-BE98_Pro" + echo "" + sleep 3 + fi + ;; + + 8) # ----------------------------------------------------------------------------------------- + while true + do + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Temperature Unit Preferences ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please indicate what Temperature Units you would prefer to use?${CClear}" + echo -e "${InvGreen} ${CClear} (C)elcius, (F)ahrenheit or (K)elvin" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} (Default = C)${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${CClear}Current: ${CGreen}$TempUnits${CClear}" + echo "" + read -p 'Temp Units (C/F/K): ' TempUnits1 + case "$TempUnits1" in + [Cc]) TempUnits="C" ; break ;; + [Ff]) TempUnits="F" ; break ;; + [Kk]) TempUnits="K" ; break ;; + *) + printf "\n*ERROR*: Please enter a valid option.${CClear}\n" + sleep 2 + ;; + esac + done + if [ -z "$TempUnits1" ]; then TempUnits="C"; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new Temperature Unit ($TempUnits) has been selected." >> $LOGFILE + ;; + + 9) # ----------------------------------------------------------------------------------------- + echo "" + if [ -f $OOKLAPATH ]; then + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Remove Ookla Speedtest Binaries ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Would you like to disable and uninstall the Ookla Speedtest binaries from RTRMON?${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${CClear}Current: ${CGreen}Ookla Speedtest Installed${CClear}" + echo "" + echo -e "Remove Speedtest binaries from RTRMON?${CClear}" + if promptyn "[y/n]: " + then + echo "" + echo "" + echo -e "${CClear}Removing Ookla Speedtest binaries..." + rm "/jffs/addons/rtrmon.d/speedtest" + rm "/jffs/addons/rtrmon.d/speedtest.5" + rm "/jffs/addons/rtrmon.d/speedtest.md" + sleep 1 + if [ ! -f $OOKLAPATH ]; then + echo "" + echo -e "${CClear}Completed removing Ookla Speedtest binaries..." + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: Ookla Speedtest binaries have been successfully removed." >> $LOGFILE + Speedtst=0 + spdtestsvrID=0 + echo "" + read -rsp $'Press any key to continue...\n' -n1 key + else + echo "" + echo -e "${CRed}ERROR: Ookla Speedtest binaries were unable to be removed...${CClear}" + echo -e "Please manually resolve issue under /jffs/addons/rtrmon.d folder" + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - ERROR: Ookla Speedtest binaries were unable to be successfully removed." >> $LOGFILE + Speedtst=1 + echo "" + read -rsp $'Press any key to continue...\n' -n1 key + fi + else + echo "" + echo "" + echo -e "${CClear}Canceling removing Ookla Speedtest binaries..." + sleep 2 + fi + + else + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Install Ookla Speedtest Binaries ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Would you like to install and enable the Ookla Speedtest binaries for use with${CClear}" + echo -e "${InvGreen} ${CClear} RTRMON? Please read the following before accepting agreement:${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} You may only use this Speedtest software and information generated from it for${CClear}" + echo -e "${InvGreen} ${CClear} personal, non-commercial use, through a command line interface on a personal${CClear}" + echo -e "${InvGreen} ${CClear} computer. Your use of this software is subject to the End User License${CClear}" + echo -e "${InvGreen} ${CClear} Agreement, Terms of Use and Privacy Policy at these URLs:${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} https://www.speedtest.net/about/eula${CClear}" + echo -e "${InvGreen} ${CClear} https://www.speedtest.net/about/terms${CClear}" + echo -e "${InvGreen} ${CClear} https://www.speedtest.net/about/privacy${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${CClear}Current: ${CGreen}Ookla Speedtest Not Installed${CClear}" + echo "" + echo -e "By typing 'y' below, you agree to these terms.${CClear}" + if promptyn "[y/n]: "; then + echo "" + echo "" + echo -e "Installing Ookla Speedtest binaries..." + echo "" + if [ "$(uname -m)" = "aarch64" ]; then + curl --silent --retry 3 "https://install.speedtest.net/app/cli/ookla-speedtest-1.2.0-linux-aarch64.tgz" -o "/jffs/addons/rtrmon.d/spdtst64.tgz" + tar -zxf /jffs/addons/rtrmon.d/spdtst64.tgz -C /jffs/addons/rtrmon.d 2>/dev/null + chmod 0755 "/jffs/addons/rtrmon.d/speedtest" + rm /jffs/addons/rtrmon.d/spdtst64.tgz + else + curl --silent --retry 3 "https://install.speedtest.net/app/cli/ookla-speedtest-1.2.0-linux-armel.tgz" -o "/jffs/addons/rtrmon.d/spdtstel.tgz" + tar -zxf /jffs/addons/rtrmon.d/spdtstel.tgz -C /jffs/addons/rtrmon.d 2>/dev/null + chmod 0755 "/jffs/addons/rtrmon.d/speedtest" + rm /jffs/addons/rtrmon.d/spdtstel.tgz + fi + if [ -f /jffs/addons/rtrmon.d/speedtest ]; then + echo -e "${CClear}Ookla Speedtest binaries installed successfully..." + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: Ookla Speedtest binaries were successfully installed." >> $LOGFILE + Speedtst=1 + echo "" + read -rsp $'Press any key to initialize Speedtest and accept license...\n' -n1 key + /jffs/addons/rtrmon.d/speedtest + cp /root/.config/ookla/speedtest-cli.json /jffs/addons/rtrmon.d/speedtest-cli.json 2>/dev/null + echo "" + read -rsp $'Press any key to continue...\n' -n1 key + else + echo -e "${CRed}ERROR: Ookla Speedtest binaries install failed...${CClear}" + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - ERROR: Ookla Speedtest binaries were unable to be successfully installed." >> $LOGFILE + Speedtst=0 + spdtestsvrID=0 + echo "" + read -rsp $'Press any key to continue...\n' -n1 key + fi + else + echo "" + echo "" + echo -e "${CClear}Canceling install of Ookla Speedtest binaries..." + Speedtst=0 + spdtestsvrID=0 + sleep 2 + fi + fi + ;; + + 10) # ----------------------------------------------------------------------------------------- + if [ "$Speedtst" == "0" ]; then return; fi + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Custom Speedtest Server ID ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please indicate if you would like to use a custom Speedtest Server ID? These IDs${CClear}" + echo -e "${InvGreen} ${CClear} can be found by running a Speedtest on your browser and noting the ID of the server${CClear}" + echo -e "${InvGreen} ${CClear} in its URL when hovering your mouse over it. Enter an ID number, or use 0 to choose${CClear}" + echo -e "${InvGreen} ${CClear} the closest server to you.${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} (Default = 0)${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${CClear}Current: ${CGreen}$spdtestsvrID${CClear}" + echo "" + read -p 'Speedtest Server ID: ' spdtestsvrID1 + spdtestsvrID2=$(echo $spdtestsvrID1 | tr -d -c 0-9) + if [ -z "$spdtestsvrID1" ]; then spdtestsvrID=0; else spdtestsvrID=$spdtestsvrID2; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: Ookla Speedtest custom server ID ($spdtestsvrID) was configured." >> $LOGFILE + ;; + + 11) # ----------------------------------------------------------------------------------------- + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Override WAN0 Interface ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please indicate if you would like to override the default interface assigned to${CClear}" + echo -e "${InvGreen} ${CClear} your local WAN0? Typically, 'eth0' is assigned to WAN0, but based on how you've${CClear}" + echo -e "${InvGreen} ${CClear} rigged your router, it might be something else. By default, RTRMON will${CClear}" + echo -e "${InvGreen} ${CClear} automatically try to determine the correct interface, however this will give${CClear}" + echo -e "${InvGreen} ${CClear} you the option to override it should you be using something else.${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} (Default = 0)${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${CClear}Current: ${CGreen}$WANOverride${CClear}" + echo "" + echo -e "${CGreen}Valid interface choices:" + + ip -br link | LC_ALL=C awk '$2 == "UP" {print $1}' > $IFLIST # Extract all valid interfaces to a text file + + LINES=$(cat $IFLIST | wc -l) #Check to see how many lines are in this file + + echo -e "${CClear}0) Auto" + + i=0 # Populate all other numbered choices + while [ $i -ne $LINES ] + do + i=$(($i+1)) + InterfaceName=$(sed -n "${i}p" $IFLIST) + echo -e "$i) $InterfaceName" + done + + echo -e "${CClear}" + echo -e "(Default = 0 (Auto), or choose one of the above)${CClear}" + + while true + do + read -p 'Choose Interface #: ' ChooseInterface + + case ${ChooseInterface#[-+]} in # Make sure we're only picking an item from the list + *[!0-9]* | '') echo ""; echo -e "\n${CRed}ERROR: Please make a valid selection${CClear}"; echo "" ;; + * ) if [ $ChooseInterface -lt 0 ] || [ $ChooseInterface -gt $LINES ]; then echo ""; echo -e "\n${CRed}Please make a valid selection${CClear}"; echo ""; else break; fi ;; + esac + + done + + if [ -z "$ChooseInterface" ] # Assign the interface name to a variable and save it + then + WANOverride="Auto" + elif [ $ChooseInterface -eq 0 ] + then + WANOverride="Auto" + else + WANOverride=$(sed -n "${ChooseInterface}p" $IFLIST) + fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: WAN0 Override ($WANOverride) was configured." >> $LOGFILE + ;; + + 12) # ----------------------------------------------------------------------------------------- + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Mark Router As iMesh Node/Repeater/Bridge ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please indicate if you would like to mark that this router is being used as an${CClear}" + echo -e "${InvGreen} ${CClear} iMesh Node, Repeater or Bridge operating mode. In cases like this, the WAN0${CClear}" + echo -e "${InvGreen} ${CClear} interface will be non-functional, and will be omitted from being captured by${CClear}" + echo -e "${InvGreen} ${CClear} RTRMON's stats.${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} (Default = No)${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + if [ "$WAN0AltModes" == "0" ]; then WAN0AltModesdisp="No"; else WAN0AltModesdisp="Yes"; fi + echo -e "${CClear}Current: ${CGreen}$WAN0AltModesdisp${CClear}" + echo "" + echo -e "Is this router an iMesh Node/Repeater/Bridge?${CClear}" + if promptyn "[y/n]: "; then + WAN0AltModes=1 + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: This device's operating mode was marked as an iMesh Node/AP/Repeater/Bridge." >> $LOGFILE + else + WAN0AltModes=0 + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: This device's operating mode was marked as a Router." >> $LOGFILE + fi + ;; + + 13) # ----------------------------------------------------------------------------------------- + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Mark VPN As Site-To-Site Only ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please indicate if you would like to mark that this router is purely being used${CClear}" + echo -e "${InvGreen} ${CClear} in a VPN Site-To-Site only configuration. In cases like this, the public-facing${CClear}" + echo -e "${InvGreen} ${CClear} IP is a private IP, which could hinder certain network connection and bandwidth$CClear}" + echo -e "${InvGreen} ${CClear} tests, and potentially cause delays and/or a lack of data.${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} By default, it is assumed that this router's VPN configuration will be marked${CClear}" + echo -e "${InvGreen} ${CClear} as being in a normal VPN provider configuration.${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} (Default = No)${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + if [ "$VPNSite2Site" == "0" ]; then VPNSite2Sitedisp="No"; else VPNSite2Sitedisp="Yes"; fi + echo -e "${CClear}Current: ${CGreen}$VPNSite2Sitedisp${CClear}" + echo "" + echo -e "Is this router purely used in a VPN Site-to-Site Configuration?${CClear}" + if promptyn "[y/n]: "; then + VPNSite2Site=1 + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: This device's VPN operating mode was marked as being in a VPN Site-to-Site only configuration." >> $LOGFILE + else + VPNSite2Site=0 + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: This device's VPN operating mode was marked as being in a Normal VPN Provider configuration." >> $LOGFILE + fi + ;; + + 14) + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Custom Event Log Size ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please indicate below how large you would like your Event Log to grow. I'm a poet${CClear}" + echo -e "${InvGreen} ${CClear} and didn't even know it. By default, with 2000 rows, you will have many months of${CClear}" + echo -e "${InvGreen} ${CClear} Event Log data." + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Use 0 to Disable, max number of rows is 9999. (Default = 2000)" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${CClear}Current: ${CGreen}$LOGSIZE${CClear}" + echo "" + read -p "Please enter Log Size (in rows)? (0-9999, e=Exit): " NEWLOGSIZE + if [ -z "$NEWLOGSIZE" ] || [ "$NEWLOGSIZE" = "e" ] + then + printf "\n[Exiting]\n"; sleep 2 + elif [ $NEWLOGSIZE -ge 0 ] && [ $NEWLOGSIZE -le 9999 ] + then + LOGSIZE="$NEWLOGSIZE" + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: New custom Event Log Size entered (in rows): $LOGSIZE" >> $LOGFILE + else + LOGSIZE=2000 + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: New custom Event Log Size entered (in rows): $LOGSIZE" >> $LOGFILE + fi + ;; + + [Ss]) # ----------------------------------------------------------------------------------------- + echo "" + { echo 'Interval='$Interval + echo 'MaxSpeedInet='$MaxSpeedInet + echo 'MaxSpeedInetUL='$MaxSpeedInetUL + echo 'MaxSpeedLAN='$MaxSpeedLAN + echo 'MaxSpeed24Ghz='$MaxSpeed24Ghz + echo 'MaxSpeed5Ghz='$MaxSpeed5Ghz + echo 'MaxSpeed6Ghz='$MaxSpeed6Ghz + echo 'TempUnits="'"$TempUnits"'"' + echo 'Speedtst='$Speedtst + echo 'spdtestsvrID='$spdtestsvrID + echo 'WANOverride="'"$WANOverride"'"' + echo 'WAN0AltModes='$WAN0AltModes + echo 'VPNSite2Site='$VPNSite2Site + echo 'LOGSIZE='$LOGSIZE + } > $CFGPATH + echo -e "\n${CClear}Applying config changes to RTRMON..." + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: New Config file was successfully written." >> $LOGFILE + sleep 3 + return + ;; + + [Ee]) # ----------------------------------------------------------------------------------------- + return + ;; + + esac + done + + else + #Create a new config file with default values to get it to a basic running state + { echo 'Interval=10' + echo 'MaxSpeedInet=1000' + echo 'MaxSpeedInetUL=50' + echo 'MaxSpeedLAN=1000' + echo 'MaxSpeed24Ghz=450' + echo 'MaxSpeed5Ghz=780' + echo 'MaxSpeed6Ghz=920' + echo 'TempUnits="C"' + echo 'Speedtst=0' + echo 'spdtestsvrID=0' + echo 'WANOverride="Auto"' + echo 'WAN0AltModes=0' + echo 'VPNSite2Site=0' + echo 'LOGSIZE=2000' + } > $CFGPATH + + #Re-run rtrmon -config to restart setup process + vconfig + + fi + +} + +# ------------------------------------------------------------------------------------------------------------------------- + +# vuninstall is a function that uninstalls and removes all traces of RTRMON from your router... +vuninstall () { + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Uninstall Utility ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} You are about to uninstall RTRMON! This action is irreversible." + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "Do you wish to proceed?${CClear}" + if promptyn "[y/n]: "; then + echo "" + echo -e "\nAre you sure? Please type 'Y' to validate you want to proceed.${CClear}" + if promptyn "[y/n]: "; then + clear + rm -r /jffs/addons/rtrmon.d + rm /jffs/scripts/rtrmon.sh + echo "" + echo -e "\nRTRMON has been uninstalled...${CClear}" + echo "" + exit 0 + else + echo "" + echo -e "\nExiting Uninstall Utility...${CClear}" + sleep 1 + return + fi + else + echo "" + echo -e "\nExiting Uninstall Utility...${CClear}" + sleep 1 + return + fi +} + + +# ------------------------------------------------------------------------------------------------------------------------- + +# vupdate is a function that provides a UI to check for script updates and allows you to install the latest version... +vupdate () { + updatecheck # Check for the latest version from source repository + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Update Utility ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} This utility allows you to check, download and install updates" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "Current Version: ${CGreen}$Version${CClear}" + echo -e "Updated Version: ${CGreen}$DLVersion${CClear}" + echo "" + if [ "$Version" == "$DLVersion" ] + then + echo -e "You are on the latest version! Would you like to download anyways?${CClear}" + echo -e "This will overwrite your local copy with the current build.${CClear}" + if promptyn "[y/n]: "; then + echo "" + echo "" + echo -e "Downloading RTRMON ${CGreen}v$DLVersion${CClear}" + curl --silent --retry 3 "https://raw.githubusercontent.com/ViktorJp/RTRMON/master/rtrmon.sh" -o "/jffs/scripts/rtrmon.sh" && chmod 755 "/jffs/scripts/rtrmon.sh" + echo "" + echo -e "Download successful!${CClear}" + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: Successfully downloaded RTRMON v$DLVersion." >> $LOGFILE + echo "" + read -rsp $'Press any key to continue...\n' -n1 key + exec sh /jffs/scripts/rtrmon.sh -monitor + else + echo "" + echo "" + echo -e "Exiting Update Utility...${CClear}" + sleep 1 + return + fi + else + echo -e "Score! There is a new version out there! Would you like to update?${CClear}" + if promptyn "[y/n]: "; then + echo "" + echo "" + echo -e "Downloading RTRMON ${CYellow}v$DLVersion${CClear}" + curl --silent --retry 3 "https://raw.githubusercontent.com/ViktorJp/RTRMON/master/rtrmon.sh" -o "/jffs/scripts/rtrmon.sh" && chmod 755 "/jffs/scripts/rtrmon.sh" + echo "" + echo -e "Download successful!${CClear}" + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: Successfully downloaded RTRMON v$DLVersion." >> $LOGFILE + echo "" + read -rsp $'Press any key to continue...\n' -n1 key + exec sh /jffs/scripts/rtrmon.sh -monitor + else + echo "" + echo "" + echo -e "Exiting Update Utility...${CClear}" + sleep 1 + return + fi + fi +} + +# ------------------------------------------------------------------------------------------------------------------------- +##----------------------------------------## +## Modified by Martinski W. [2024-Nov-02] ## +##----------------------------------------## +# Function that sets up, configures and allows you to launch RTRMON on your router... +vsetup() +{ + _SetUpTimeoutCmdVars_ + + # Check for and add an alias for RTRMON # + if ! grep -F "sh /jffs/scripts/rtrmon.sh" /jffs/configs/profile.add >/dev/null 2>/dev/null; then + echo "alias rtrmon=\"sh /jffs/scripts/rtrmon.sh\" # RTRMON" >> /jffs/configs/profile.add + fi + + while true + do + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} RTRMON Main Setup and Configuration Menu ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Please choose from the various options below, which allow you to perform high level${CClear}" + echo -e "${InvGreen} ${CClear} actions in the management of the RTRMON script.${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(1)${CClear} : Setup and Configure RTRMON" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(2)${CClear} : Force Re-install Entware Dependencies" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(3)${CClear} : Check for latest updates" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(4)${CClear} : View logs" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(5)${CClear} : Uninstall" + if [ "$FromUI" == "0" ]; then + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite} | ${CClear}" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(6)${CClear} : Launch RTRMON into Normal Monitoring Mode" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(7)${CClear} : Launch RTRMON into Normal Monitoring Mode w/ SCREEN" + fi + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite} | ${CClear}" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(e)${CClear} : Exit" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + if [ "$FromUI" == "0" ]; then + read -p "Please select? (1-7, e=Exit): " InstallSelection + else + read -p "Please select? (1-5, e=Exit): " InstallSelection + fi + + # Execute chosen selections + case "$InstallSelection" in + + 1) # Check for existence of entware, and if so proceed and install the timeout package, then run RTRMON -config + clear + if [ -f "/opt/bin/column" ] && [ -f "/opt/bin/timeout" ] && [ -f "/opt/sbin/screen" ] && [ -f "/opt/bin/nmap" ] && [ -f "/opt/bin/jq" ] && [ -f "/opt/bin/iftop" ] + then + vconfig + else + echo -e "${InvGreen} ${InvDkGray}${CWhite} Install Dependencies ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Missing dependencies required by RTRMON will be installed during this process." + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "RTRMON will require the installation of CoreUtils-Timeout, Screen and Nmap utilities." + echo -e "These utilities require you to have Entware already installed using the AMTM tool. If" + echo -e "Entware is present, the Timeout, Screen and Nmap utilities will be downloaded and" + echo -e "installed during this setup process, and utilized by RTRMON." + echo "" + echo -e "${CGreen}CoreUtils-Timeout${CClear} is a utility that provides more stability for certain routers (like" + echo -e "the RT-AC86U) which has a tendency to randomly hang scripts running on this router model." + echo "" + echo -e "${CGreen}Screen${CClear} is a utility that allows you to run SSH scripts in a standalone" + echo -e "environment directly on the router itself, instead of running your commands or a script" + echo -e "from a network-attached SSH client. This can provide greater stability due to it running" + echo -e "from the router itself." + echo "" + echo -e "${CGreen}Nmap${CClear} is a network discovery and security auditing tool that is used to scan your LAN," + echo -e "WAN and VPN connections for open ports." + echo "" + echo -e "${CGreen}JQuery${CClear} is a utility for querying data across the internet for the purposes of" + echo -e "interacting with the various VPN providers to get a list of APIs available VPN hosts in" + echo -e "the selected country." + echo "" + echo -e "${CGreen}iftop${CClear} is a utility for querying connection and bandwidth data." + echo "" + echo -e "${CGreen}Column${CClear} is a utility used to neatly arrange data on screen." + echo "" + echo -e "Your router model is: ${CGreen}${RouterModel}${CClear}" + echo "" + echo -e "Ready to install?" + if promptyn "[y/n]: " + then + if [ -d "/opt" ]; then # Does entware exist? If yes proceed, if no error out. + echo "" + echo -e "\n${CClear}Updating Entware Packages..." + echo "" + opkg update + echo "" + echo -e "Installing Entware ${CGreen}CoreUtils-Timeout${CClear} Package..." + echo "" + opkg install coreutils-timeout + echo "" + echo -e "Installing Entware ${CGreen}Screen Package${CClear}..." + echo "" + opkg install screen + echo "" + echo -e "Installing Entware ${CGreen}Nmap${CClear} Package..." + echo "" + opkg install nmap + echo "" + echo -e "Installing Entware ${CGreen}JQuery${CClear} Package..." + echo "" + opkg install jq + echo "" + echo -e "Installing Entware ${CGreen}iftop${CClear} Package..." + echo "" + opkg install iftop + echo "" + echo -e "Installing Entware ${CGreen}Column${CClear} Package..." + echo "" + opkg install column + echo "" + echo -e "Install completed..." + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: Entware dependencies were successfully installed." >> $LOGFILE + echo "" + read -rsp $'Press any key to continue...\n' -n1 key + echo "" + echo -e "Executing RTRMON Configuration Utility..." + sleep 2 + vconfig + else + clear + echo -e "${CRed}ERROR: Entware was not found on this router...${CClear}" + echo -e "Please install Entware using the AMTM utility before proceeding..." + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - ERROR: Entware was not found on this router. Please install using AMTM utility." >> $LOGFILE + echo "" + sleep 3 + fi + else + echo "" + echo -e "\nExecuting RTRMON Configuration Utility..." + sleep 2 + vconfig + fi + fi + ;; + + + 2) # Force re-install the CoreUtils timeout/screen package + clear + echo -e "${InvGreen} ${InvDkGray}${CWhite} Re-install Dependencies ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} Missing dependencies required by RTRMON will be re-installed during this process." + echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "VPNMON-R3 has some dependencies in order to function correctly, namely, CoreUtils-Timeout" + echo -e "RTRMON will require the installation of CoreUtils-Timeout, Screen, Nmap, JQ and iftop" + echo -e "utilities. These utilities require you to have Entware already installed using AMTM. If" + echo -e "Entware is present, the Timeout, Screen, Nmap, JQ and iftop utilities will be downloaded" + echo -e "and re-installed during this setup process, and utilized by RTRMON." + echo "" + echo -e "${CGreen}CoreUtils-Timeout${CClear} is a utility that provides more stability for certain routers (like" + echo -e "the RT-AC86U) which has a tendency to randomly hang scripts running on this router model." + echo "" + echo -e "${CGreen}Screen${CClear} is a utility that allows you to run SSH scripts in a standalone" + echo -e "environment directly on the router itself, instead of running your commands or a script" + echo -e "from a network-attached SSH client. This can provide greater stability due to it running" + echo -e "from the router itself." + echo "" + echo -e "${CGreen}Nmap${CClear} is a network discovery and security auditing tool that is used to scan your LAN," + echo -e "WAN and VPN connections for open ports." + echo "" + echo -e "${CGreen}JQuery${CClear} is a utility for querying data across the internet for the purposes of" + echo -e "interacting with the various VPN providers to get a list of APIs available VPN hosts in" + echo -e "the selected country." + echo "" + echo -e "${CGreen}iftop${CClear} is a utility for querying connection and bandwidth data." + echo "" + echo -e "${CGreen}Column${CClear} is a utility used to neatly arrange data on screen." + echo "" + echo -e "Your router model is: ${CGreen}${RouterModel}${CClear}" + echo "" + echo -e "Force Re-install?" + if promptyn "[y/n]: " + then + if [ -d "/opt" ]; then # Does entware exist? If yes proceed, if no error out. + echo "" + echo -e "\n${CClear}Updating Entware Packages..." + echo "" + opkg update + echo "" + echo -e "Force Re-installing Entware ${CGreen}CoreUtils-Timeout${CClear} Package..." + echo "" + opkg install --force-reinstall coreutils-timeout + echo "" + echo -e "Force Re-installing Entware ${CGreen}Screen${CClear} Package..." + echo "" + opkg install --force-reinstall screen + echo "" + echo -e "Force Re-installing Entware ${CGreen}Nmap${CClear} Package..." + echo "" + opkg install --force-reinstall nmap + echo "" + echo -e "Force Re-installing Entware ${CGreen}JQuery${CClear} Package..." + echo "" + opkg install --force-reinstall jq + echo "" + echo -e "Force Re-installing Entware ${CGreen}iftop${CClear} Package..." + echo "" + opkg install --force-reinstall iftop + echo "" + echo -e "Force Re-installing Entware ${CGreen}Column${CClear} Package..." + echo "" + opkg install --force-reinstall column + echo "" + echo -e "Re-install completed..." + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: Entware dependencies were successfully re-installed." >> $LOGFILE + echo "" + read -rsp $'Press any key to continue...\n' -n1 key + else + clear + echo -e "${CRed}ERROR: Entware was not found on this router...${CClear}" + echo -e "Please install Entware using the AMTM utility before proceeding..." + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - ERROR: Entware was not found on this router. Please install using AMTM utility." >> $LOGFILE + echo "" + sleep 3 + fi + fi + ;; + + 3) + echo "" + vupdate + ;; + + 6) + echo "" + echo -e "\n${CGreen}Launching RTRMON into Monitor Mode...${CClear}" + sleep 2 + exec sh $APPPATH -monitor + ;; + + 7) + echo "" + echo -e "\n${CGreen}Launching RTRMON into Monitor Mode with Screen Utility...${CClear}" + sleep 2 + exec sh $APPPATH -screen + ;; + + 4) + echo "" + vlogs + ;; + + 5) + echo "" + vuninstall + ;; + + [Ee]) + echo -e "${CClear}" + timer="$Interval" + break + ;; + + *) + echo "" + echo -e "${CRed}Invalid choice - Please enter a valid option...${CClear}" + echo "" + sleep 2 + ;; + + esac + done +} + +# ------------------------------------------------------------------------------------------------------------------------- + +# get_wan_setting was "borrowed" graciously from @dave14305 from his FlexQoS script to determine the active WAN connection. +# Thanks much for your troubleshooting help as we tackled how to best derive the active WAN interface, Dave! +get_wan_setting() { + local varname varval + varname="${1}" + prefixes="wan0_ wan1_" + + if [ "$($timeoutcmd$timeoutsec nvram get wans_mode)" = "lb" ] ; then + for prefix in $prefixes; do + state="$($timeoutcmd$timeoutsec nvram get "${prefix}"state_t)" + sbstate="$($timeoutcmd$timeoutsec nvram get "${prefix}"sbstate_t)" + auxstate="$($timeoutcmd$timeoutsec nvram get "${prefix}"auxstate_t)" + + # is_wan_connect() + [ "${state}" = "2" ] || continue + [ "${sbstate}" = "0" ] || continue + [ "${auxstate}" = "0" ] || [ "${auxstate}" = "2" ] || continue + + # get_wan_ifname() + proto="$($timeoutcmd$timeoutsec nvram get "${prefix}"proto)" + if [ "${proto}" = "pppoe" ] || [ "${proto}" = "pptp" ] || [ "${proto}" = "l2tp" ] ; then + varval="$($timeoutcmd$timeoutsec nvram get "${prefix}"pppoe_"${varname}")" + else + varval="$($timeoutcmd$timeoutsec nvram get "${prefix}""${varname}")" + fi + done + else + for prefix in $prefixes; do + primary="$($timeoutcmd$timeoutsec nvram get "${prefix}"primary)" + [ "${primary}" = "1" ] && break + done + + proto="$($timeoutcmd$timeoutsec nvram get "${prefix}"proto)" + if [ "${proto}" = "pppoe" ] || [ "${proto}" = "pptp" ] || [ "${proto}" = "l2tp" ] ; then + varval="$($timeoutcmd$timeoutsec nvram get "${prefix}"pppoe_"${varname}")" + else + varval="$($timeoutcmd$timeoutsec nvram get "${prefix}""${varname}")" + fi + fi + printf "%s" "${varval}" +} # get_wan_setting + +# ------------------------------------------------------------------------------------------------------------------------- + +# gettopstats gathers the majority of cpu and memory related stats directly from the TOP utility +##----------------------------------------## +## Modified by Martinski W. [2024-Nov-02] ## +##----------------------------------------## +gettopstats () +{ + local numFields + + TotalMem="$(top -bn1 | head -n3 | grep -E '^Mem:|^CPU:|^Load' | awk 'NR==1 {print $2, $4, $6, $8, $10} NR==2 {print $2, $4, $6, $8, $14} NR==3 {print $3, $4, $5}' 2>/dev/null)" + + numFields="$(echo $TotalMem | awk -F ' ' '{print NF}')" + [ "$numFields" -lt 13 ] && return 1 + + #totalmemory based on the power of 2 to determine nearest estimated installed RAM + memtotal="$(awk '/^MemTotal:/ {print $2}' /proc/meminfo)" + totalreportedphysmem=$(awk 'BEGIN { printf "%.0f", ('"$memtotal"' / 1000) }') + next_power_of_2=$(awk -v num="$totalreportedphysmem" ' + BEGIN { + if (num == 0) { + print 1; + exit; + } + num--; + num = or(num, rshift(num, 1)); + num = or(num, rshift(num, 2)); + num = or(num, rshift(num, 4)); + num = or(num, rshift(num, 8)); + num = or(num, rshift(num, 16)); + # num = or(num, rshift(num, 32)); + num++; + print num; + } + ') + totalmemory="$next_power_of_2" + + memfree="$(awk '/^MemFree:/ {print $2}' /proc/meminfo)" + membuff="$(awk '/^Buffers:/ {print $2}' /proc/meminfo)" + memcach="$(awk '/^Cached:/ {print $2}' /proc/meminfo)" + memfree="$(awk 'BEGIN { printf "%.0f", ('"$memfree"' + '"$membuff"' + '"$memcach"') }')" + memshrd="$(awk '/^Shmem:/ {print $2}' /proc/meminfo)" + memused="$(awk 'BEGIN { printf "%.0f", ('"$totalmemory"' * 1000 - '"$memfree"') }')" + + cpuusr="$(echo $TotalMem | awk '{print $6}' | sed 's/%$//' | cut -d . -f 1)" + cpusys="$(echo $TotalMem | awk '{print $7}' | sed 's/%$//' | cut -d . -f 1)" + cpunice="$(echo $TotalMem | awk '{print $8}' | sed 's/%$//' | cut -d . -f 1)" + cpuidle="$(echo $TotalMem | awk '{print $9}' | sed 's/%$//' | cut -d . -f 1)" + cpuirq="$(echo $TotalMem | awk '{print $10}' | sed 's/%$//' | cut -d . -f 1)" + displaycpuusr="$(echo $TotalMem | awk '{print $6}' | sed 's/%$//')" + displaycpusys="$(echo $TotalMem | awk '{print $7}' | sed 's/%$//')" + displaycpunice="$(echo $TotalMem | awk '{print $8}' | sed 's/%$//')" + displaycpuidle="$(echo $TotalMem | awk '{print $9}' | sed 's/%$//')" + displaycpuirq="$(echo $TotalMem | awk '{print $10}' | sed 's/%$//')" + cpuload1m="$(echo $TotalMem | awk '{print $11}')" + cpuload5m="$(echo $TotalMem | awk '{print $12}')" + cpuload15m="$(echo $TotalMem | awk '{print $13}')" + + memused1="$((memused1 + memused))" + memfree1="$((memfree1 + memfree))" + memshrd1="$((memshrd1 + memshrd))" + membuff1="$((membuff1 + membuff))" + memcach1="$((memcach1 + memcach))" + cpuusr1="$((cpuusr1 + cpuusr))" + cpusys1="$((cpusys1 + cpusys))" + cpunice1="$((cpunice1 + cpunice))" + cpuidle1="$((cpuidle1 + cpuidle))" + cpuirq1="$((cpuirq1 + cpuirq))" + + displaycpuusr1="$(awk -v v1=$displaycpuusr1 -v v2=$displaycpuusr 'BEGIN{printf "%0.2f\n", v1+v2}')" + displaycpusys1="$(awk -v v1=$displaycpusys1 -v v2=$displaycpusys 'BEGIN{printf "%0.2f\n", v1+v2}')" + displaycpunice1="$(awk -v v1=$displaycpunice1 -v v2=$displaycpunice 'BEGIN{printf "%0.2f\n", v1+v2}')" + displaycpuidle1="$(awk -v v1=$displaycpuidle1 -v v2=$displaycpuidle 'BEGIN{printf "%0.2f\n", v1+v2}')" + displaycpuirq1="$(awk -v v1=$displaycpuirq1 -v v2=$displaycpuirq 'BEGIN{printf "%0.2f\n", v1+v2}')" + + return 0 +} + +# ------------------------------------------------------------------------------------------------------------------------- + +# oldstats holds the old (current) stats that are being used to display stats on-screen +oldstats() +{ + oldcpuusr1=$cpuusr1 + oldcpusys1=$cpusys1 + oldcpunice1=$cpunice1 + oldcpuidle1=$cpuidle1 + oldcpuirq1=$cpuirq1 + olddisplaycpuusr1=$displaycpuusr1 + olddisplaycpusys1=$displaycpusys1 + olddisplaycpunice1=$displaycpunice1 + olddisplaycpuidle1=$displaycpuidle1 + olddisplaycpuirq1=$displaycpuirq1 + oldF_cputemp=$F_cputemp + oldmemused2=$memused2 + oldmemfree2=$memfree2 + oldmemshrd2=$memshrd2 + oldmembuff2=$membuff2 + oldmemcach2=$memcach2 + oldtotalmemory=$totalmemory + oldnvramfree=$nvramfree + oldnvramused=$nvramused + oldtotalnvram=$totalnvram + oldjffstotal=$jffstotal + oldjffsused=$jffsused + oldswaptotal=$swaptotal + oldswapused=$swapused + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + oldwan0ip=$wan0ip + oldwan1ip=$wan1ip + fi + olddns1ip=$dns1ip + olddns2ip=$dns2ip + oldwanip6=$wanip6 + oldlanip6=$lanip6 + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + oldwanrxmbrate=$wanrxmbrate + oldwantxmbrate=$wantxmbrate + fi + oldw24rxmbrate=$w24rxmbrate + oldw24txmbrate=$w24txmbrate + oldw5rxmbrate=$w5rxmbrate + oldw5txmbrate=$w5txmbrate + oldw24temp=$w24temp + oldw5temp=$w5temp + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then + oldw52rxmbrate=$w52rxmbrate + oldw52txmbrate=$w52txmbrate + oldw52temp=$w52temp + fi + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then + oldw6rxmbrate=$w6rxmbrate + oldw6txmbrate=$w6txmbrate + oldw6temp=$w6temp + fi + if [ "$FourBandCustom56624" == "True" ]; then + oldw62rxmbrate=$w62rxmbrate + oldw62txmbrate=$w62txmbrate + oldw62temp=$w62temp + fi + + oldlanip=$lanip + oldlanrxmbrate=$lanrxmbrate + oldlantxmbrate=$lantxmbrate + + oldvpnrxmbrate=$vpnrxmbrate + oldvpntxmbrate=$vpntxmbrate + oldvpn2rxmbrate=$vpn2rxmbrate + oldvpn2txmbrate=$vpn2txmbrate + oldvpn3rxmbrate=$vpn3rxmbrate + oldvpn3txmbrate=$vpn3txmbrate + oldvpn4rxmbrate=$vpn4rxmbrate + oldvpn4txmbrate=$vpn4txmbrate + oldvpn5rxmbrate=$vpn5rxmbrate + oldvpn5txmbrate=$vpn5txmbrate + oldvpn1ip=$vpn1ip + oldvpn1city=$vpn1city + oldvpn2ip=$vpn2ip + oldvpn2city=$vpn2city + oldvpn3ip=$vpn3ip + oldvpn3city=$vpn3city + oldvpn4ip=$vpn4ip + oldvpn4city=$vpn4city + oldvpn5ip=$vpn5ip + oldvpn5city=$vpn5city + + oldwg1rxmbrate=$wg1rxmbrate + oldwg1txmbrate=$wg1txmbrate + oldwg2rxmbrate=$wg2rxmbrate + oldwg2txmbrate=$wg2txmbrate + oldwg3rxmbrate=$wg3rxmbrate + oldwg3txmbrate=$wg3txmbrate + oldwg4rxmbrate=$wg4rxmbrate + oldwg4txmbrate=$wg4txmbrate + oldwg5rxmbrate=$wg5rxmbrate + oldwg5txmbrate=$wg5txmbrate + oldwg1ip=$wg1ip + oldwg1city=$wg1city + oldwg2ip=$wg2ip + oldwg2city=$wg2city + oldwg3ip=$wg3ip + oldwg3city=$wg3city + oldwg4ip=$wg4ip + oldwg4city=$wg4city + oldwg5ip=$wg5ip + oldwg5city=$wg5city + + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + oldwanrxmbratedisplay=$wanrxmbratedisplay + oldwantxmbratedisplay=$wantxmbratedisplay + fi + oldw24rxmbratedisplay=$w24rxmbratedisplay + oldw24txmbratedisplay=$w24txmbratedisplay + oldw5rxmbratedisplay=$w5rxmbratedisplay + oldw5txmbratedisplay=$w5txmbratedisplay + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then + oldw52rxmbratedisplay=$w52rxmbratedisplay + oldw52txmbratedisplay=$w52txmbratedisplay + fi + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then + oldw6rxmbratedisplay=$w6rxmbratedisplay + oldw6txmbratedisplay=$w6txmbratedisplay + fi + if [ "$FourBandCustom56624" == "True" ]; then + oldw62rxmbratedisplay=$w62rxmbratedisplay + oldw62txmbratedisplay=$w62txmbratedisplay + fi + oldlanrxmbratedisplay=$lanrxmbratedisplay + oldlantxmbratedisplay=$lantxmbratedisplay + + oldvpnrxmbratedisplay=$vpnrxmbratedisplay + oldvpntxmbratedisplay=$vpntxmbratedisplay + oldvpn2rxmbratedisplay=$vpn2rxmbratedisplay + oldvpn2txmbratedisplay=$vpn2txmbratedisplay + oldvpn3rxmbratedisplay=$vpn3rxmbratedisplay + oldvpn3txmbratedisplay=$vpn3txmbratedisplay + oldvpn4rxmbratedisplay=$vpn4rxmbratedisplay + oldvpn4txmbratedisplay=$vpn4txmbratedisplay + oldvpn5rxmbratedisplay=$vpn5rxmbratedisplay + oldvpn5txmbratedisplay=$vpn5txmbratedisplay + + oldwg1rxmbratedisplay=$wg1rxmbratedisplay + oldwg1txmbratedisplay=$wg1txmbratedisplay + oldwg2rxmbratedisplay=$wg2rxmbratedisplay + oldwg2txmbratedisplay=$wg2txmbratedisplay + oldwg3rxmbratedisplay=$wg3rxmbratedisplay + oldwg3txmbratedisplay=$wg3txmbratedisplay + oldwg4rxmbratedisplay=$wg4rxmbratedisplay + oldwg4txmbratedisplay=$wg4txmbratedisplay + oldwg5rxmbratedisplay=$wg5rxmbratedisplay + oldwg5txmbratedisplay=$wg5txmbratedisplay +} + +# ------------------------------------------------------------------------------------------------------------------------- +##----------------------------------------## +## Modified by Martinski W. [2024-Nov-04] ## +##----------------------------------------## +# Calculates and captures, well, all the current stats from their sources ;) +calculatestats() +{ + + RM_END_TIME="$(date +%s)" + RM_ELAPSED_TIME=$((RM_END_TIME - RM_START_TIME)) + [ "$RM_ELAPSED_TIME" -eq 0 ] && return 1 + + # CPU - Usage + if [ -n "$cpuusr1" ]; then cpuusr1=$((cpuusr1 / Interval)); else cpuusr1=0; fi + if [ -n "$cpusys1" ]; then cpusys1=$((cpusys1 / Interval)); else cpusys1=0; fi + if [ -n "$cpunice1" ]; then cpunice1=$((cpunice1 / Interval)); else cpunice1=0; fi + if [ -n "$cpuidle1" ]; then cpuidle1=$((cpuidle1 / Interval)); else cpuidle1=0; fi + if [ -n "$cpuirq1" ]; then cpuirq1=$((cpuirq1 / Interval)); else cpuirq1=0; fi + if [ -n "$displaycpuusr1" ]; then displaycpuusr1=$(awk -v rb=$displaycpuusr1 -v intv=$Interval 'BEGIN{printf "%0.2f\n", rb/intv}'); else displaycpuusr1=0; fi + if [ -n "$displaycpusys1" ]; then displaycpusys1=$(awk -v rb=$displaycpusys1 -v intv=$Interval 'BEGIN{printf "%0.2f\n", rb/intv}'); else displaycpusys1=0; fi + if [ -n "$displaycpunice1" ]; then displaycpunice1=$(awk -v rb=$displaycpunice1 -v intv=$Interval 'BEGIN{printf "%0.2f\n", rb/intv}'); else displaycpunice1=0; fi + if [ -n "$displaycpuidle1" ]; then displaycpuidle1=$(awk -v rb=$displaycpuidle1 -v intv=$Interval 'BEGIN{printf "%0.2f\n", rb/intv}'); else displaycpuidle1=0; fi + if [ -n "$displaycpuirq1" ]; then displaycpuirq1=$(awk -v rb=$displaycpuirq1 -v intv=$Interval 'BEGIN{printf "%0.2f\n", rb/intv}'); else displaycpuirq1=0; fi + + # CPU - Temp - borrowed from @Maverickcdn - thank you! + if [ -f /sys/class/thermal/thermal_zone0/temp ]; then + F_cputemp=$($timeoutcmd$timeoutsec cat /sys/class/thermal/thermal_zone0/temp | cut -c -2) + elif [ -f /proc/dmu/temperature ]; then # Thanks to PeterR for the bug report on AC68U's - hopefully this will fix that + F_cputemp=$($timeoutcmd$timeoutsec cat /proc/dmu/temperature | cut -c19-20) + fi + + # Memory - Usage + if [ -n "$memused1" ]; then memused1=$((memused1 / Interval)); else memused1=0; fi + if [ -n "$memfree1" ]; then memfree1=$((memfree1 / Interval)); else memfree1=0; fi + if [ -n "$memshrd1" ]; then memshrd1=$((memshrd1 / Interval)); else memshrd1=0; fi + if [ -n "$membuff1" ]; then membuff1=$((membuff1 / Interval)); else membuff1=0; fi + if [ -n "$memcach1" ]; then memcach1=$((memcach1 / Interval)); else memcach1=0; fi + + totalphysmem="$totalmemory" + + memused2=$(awk 'BEGIN { printf "%.0f", ('"$memused1"' / 1000) }') + memfree2=$(awk 'BEGIN { printf "%.0f", ('"$memfree1"' / 1000) }') + memshrd2=$(awk 'BEGIN { printf "%.0f", ('"$memshrd1"' / 1000) }') + membuff2=$(awk 'BEGIN { printf "%.0f", ('"$membuff1"' / 1000) }') + memcach2=$(awk 'BEGIN { printf "%.0f", ('"$memcach1"' / 1000) }') + + # Memory - NVRAM -- Many thanks to @RMerlin, @SomewhereOverTheRainbow and @Ranger802004 for your help finding NVRAM stats + eval "$($timeoutcmd$timeoutsec nvram show >/tmp/output.txt 2> /tmp/size.txt)" + chmod 755 /tmp/size.txt + nvramtotals=$(cat /tmp/size.txt | grep size: | awk '{print $2, $4}' 2>/dev/null) + nvramused="$(echo $nvramtotals | awk '{print $1}')" + nvramfree="$(echo $nvramtotals | awk '{print $2}' | sed 's/[)(]//g')" + if [ -z $nvramused ] || [ -z $nvramfree ]; then + nvramused=10000 # incase the values coming back from this file are blank, use temporary fillers + totalnvram=20000 + else + totalnvram="$((nvramused + nvramfree))" + fi + + # Disk - JFFS + disk_use=$($timeoutcmd$timeoutsec df -P | grep -E '/jffs' | awk '{print $2, $3}') + jffstotal="$(echo $disk_use | awk '{print $1}')" + jffsused="$(echo $disk_use | awk '{print $2}')" + jffstotal=$(awk 'BEGIN { printf "%.0f", ('"$jffstotal"' / 1000) }') + jffsused=$(awk 'BEGIN { printf "%.0f", ('"$jffsused"' / 1000) }') + + # Disk - Swap file + swap_use=$($timeoutcmd$timeoutsec /usr/bin/free | awk 'NR==4 {print $2, $3}' 2>/dev/null) + swaptotal="$(echo $swap_use | awk '{print $1}')" + swapused="$(echo $swap_use | awk '{print $2}')" + swaptotal=$(awk 'BEGIN { printf "%.0f", ('"$swaptotal"' / 1000) }') + swapused=$(awk 'BEGIN { printf "%.0f", ('"$swapused"' / 1000) }') + if [ $swaptotal == "0" ]; then swaptotal=100; fi + + # Disk - SD devices + df | grep /dev/sd > /jffs/addons/rtrmon.d/sdresult.txt 2>/dev/null + + # Network - WAN/LAN/DNS IP Addresses + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ] + then + wan0ip=$($timeoutcmd$timeoutsec nvram get wan0_ipaddr) + wan1ip=$($timeoutcmd$timeoutsec nvram get wan1_ipaddr) + fi + lanip=$($timeoutcmd$timeoutsec nvram get lan_ipaddr) + dns1ip="$($timeoutcmd$timeoutsec nvram get wan0_dns | awk '{print $1}')" + dns2ip="$($timeoutcmd$timeoutsec nvram get wan0_dns | awk '{print $2}')" + dns3ip="$($timeoutcmd$timeoutsec nvram get wan1_dns | awk '{print $1}')" + dns4ip="$($timeoutcmd$timeoutsec nvram get wan1_dns | awk '{print $2}')" + + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ] + then + if [ -z $wan0ip ]; then dns1ip="0.0.0.0"; fi + if [ -z $wan1ip ]; then dns1ip="0.0.0.0"; fi + fi + if [ -z $lanip ]; then dns1ip="0.0.0.0"; fi + if [ -z $dns1ip ]; then dns1ip="0.0.0.0"; fi + if [ -z $dns2ip ]; then dns2ip="0.0.0.0"; fi + if [ $dns1ip == "0.0.0.0" ] && [ ! -z $dns3ip ]; then dns1ip=$dns3ip; fi + if [ $dns2ip == "0.0.0.0" ] && [ ! -z $dns4ip ]; then dns2ip=$dns4ip; fi + if [ "$vpn1on" == "False" ]; then vpn1ip="0.0.0.0"; fi + if [ "$vpn2on" == "False" ]; then vpn2ip="0.0.0.0"; fi + if [ "$vpn3on" == "False" ]; then vpn3ip="0.0.0.0"; fi + if [ "$vpn4on" == "False" ]; then vpn4ip="0.0.0.0"; fi + if [ "$vpn5on" == "False" ]; then vpn5ip="0.0.0.0"; fi + if [ "$wg1on" == "False" ]; then wg1ip="0.0.0.0"; fi + if [ "$wg2on" == "False" ]; then wg2ip="0.0.0.0"; fi + if [ "$wg3on" == "False" ]; then wg3ip="0.0.0.0"; fi + if [ "$wg4on" == "False" ]; then wg4ip="0.0.0.0"; fi + if [ "$wg5on" == "False" ]; then wg5ip="0.0.0.0"; fi + + # Many thanks to @SomewhereOverTheRainbow for his help and suggestions on getting IP6 info! + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + wanip6="$(ip -o -6 addr list "$WANIFNAME" scope global | awk 'NR==1{ split($4, ip_addr, "/"); print ip_addr[1] }')" + fi + lanip6="$(ip -o -6 addr list br0 scope global | awk 'NR==1{ split($4, ip_addr, "/"); print ip_addr[1] }')" + + # Network - Wifi - Temp + # Standard Dual-Band config + w24tempraw=$($timeoutcmd$timeoutsec wl -i $ifname24 phy_tempsense | awk '{print $1}' ) >/dev/null 2>&1 + w5tempraw=$($timeoutcmd$timeoutsec wl -i $ifname5 phy_tempsense | awk '{print $1}' ) >/dev/null 2>&1 + if [ -z $w24tempraw ] || [ $w24tempraw -eq 0 ]; then w24tempraw=1; fi #in case it does not return a valid number + if [ -z $w5tempraw ] || [ $w5tempraw -eq 0 ]; then w5tempraw=1; fi + w24temp=$(awk -v v1=$w24tempraw 'BEGIN{printf "\n" (v1/2)+20}' | cut -d . -f 1) + w5temp=$(awk -v v1=$w5tempraw 'BEGIN{printf "\n" (v1/2)+20}' | cut -d . -f 1) + + # Tri or Quad Band 5GHz + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then + w52tempraw=$($timeoutcmd$timeoutsec wl -i $ifname52 phy_tempsense | awk '{print $1}' ) >/dev/null 2>&1 + if [ -z $w52tempraw ] || [ $w52tempraw -eq 0 ]; then w52tempraw=1; fi + w52temp=$(awk -v v1=$w52tempraw 'BEGIN{printf "\n" (v1/2)+20}' | cut -d . -f 1) + fi + # Tri or Quad-Band 6GHz + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then + w6tempraw=$($timeoutcmd$timeoutsec wl -i $ifname6 phy_tempsense | awk '{print $1}' ) >/dev/null 2>&1 + if [ -z $w6tempraw ] || [ $w6tempraw -eq 0 ]; then w6tempraw=1; fi + w6temp=$(awk -v v1=$w6tempraw 'BEGIN{printf "\n" (v1/2)+20}' | cut -d . -f 1) + fi + if [ "$FourBandCustom56624" == "True" ]; then + w62tempraw=$($timeoutcmd$timeoutsec wl -i $ifname62 phy_tempsense | awk '{print $1}' ) >/dev/null 2>&1 + if [ -z $w62tempraw ] || [ $w62tempraw -eq 0 ]; then w62tempraw=1; fi + w62temp=$(awk -v v1=$w62tempraw 'BEGIN{printf "\n" (v1/2)+20}' | cut -d . -f 1) + fi + + # Network - Wifi - Up/Down via Scheduler + if [ "$FourBandCustom55624" == "True" ]; then + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl0_sched_v2) ]; then w5udsched="Scheduler[+]"; else w5udsched="Scheduler[-]"; fi + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl1_sched_v2) ]; then w52udsched="Scheduler[+]"; else w52udsched="Scheduler[-]"; fi + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl2_sched_v2) ]; then w6udsched="Scheduler[+]"; else w6udsched="Scheduler[-]"; fi + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl3_sched_v2) ]; then w24udsched="Scheduler[+]"; else w24udsched="Scheduler[-]"; fi + elif [ "$FourBandCustom56624" == "True" ]; then + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl0_sched_v2) ]; then w5udsched="Scheduler[+]"; else w5udsched="Scheduler[-]"; fi + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl1_sched_v2) ]; then w6udsched="Scheduler[+]"; else w6udsched="Scheduler[-]"; fi + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl2_sched_v2) ]; then w62udsched="Scheduler[+]"; else w62udsched="Scheduler[-]"; fi + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl3_sched_v2) ]; then w24udsched="Scheduler[+]"; else w24udsched="Scheduler[-]"; fi + elif [ "$ThreeBand2456" == "True" ]; then + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl0_sched_v2) ]; then w24udsched="Scheduler[+]"; else w24udsched="Scheduler[-]"; fi + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl1_sched_v2) ]; then w5udsched="Scheduler[+]"; else w5udsched="Scheduler[-]"; fi + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl2_sched_v2) ]; then w6udsched="Scheduler[+]"; else w6udsched="Scheduler[-]"; fi + elif [ "$ThreeBand2455" == "True" ]; then + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl0_sched_v2) ]; then w24udsched="Scheduler[+]"; else w24udsched="Scheduler[-]"; fi + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl1_sched_v2) ]; then w5udsched="Scheduler[+]"; else w5udsched="Scheduler[-]"; fi + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl2_sched_v2) ]; then w52udsched="Scheduler[+]"; else w52udsched="Scheduler[-]"; fi + else + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl0_sched_v2) ]; then w24udsched="Scheduler[+]"; else w24udsched="Scheduler[-]"; fi + if [ ! -z $($timeoutcmd$timeoutsec nvram get wl1_sched_v2) ]; then w5udsched="Scheduler[+]"; else w5udsched="Scheduler[-]"; fi + fi + + w24updown=$($timeoutcmd$timeoutsec wl -i $ifname24 bss | awk '{print toupper($1)}' ) >/dev/null 2>&1 + w5updown=$($timeoutcmd$timeoutsec wl -i $ifname5 bss | awk '{print toupper($1)}' ) >/dev/null 2>&1 + if [ -z "$w24updown" ]; then w24updown="UP"; fi + if [ -z "$w5updown" ]; then w5updown="UP"; fi + + # Tri or Quad Band 5GHz + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then + w52updown=$($timeoutcmd$timeoutsec wl -i $ifname52 bss | awk '{print toupper($1)}' ) >/dev/null 2>&1 + if [ -z "$w52updown" ]; then w52updown="UP"; fi + fi + # Tri or Quad-Band 6GHz + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then + w6updown=$($timeoutcmd$timeoutsec wl -i $ifname6 bss | awk '{print toupper($1)}' ) >/dev/null 2>&1 + if [ -z $w6updown ]; then w6updown="UP"; fi + fi + if [ "$FourBandCustom56624" == "True" ]; then + w62updown=$($timeoutcmd$timeoutsec wl -i $ifname62 bss | awk '{print toupper($1)}' ) >/dev/null 2>&1 + if [ -z $w62updown ]; then w62updown="UP"; fi + fi + + # Network - Wifi - Traffic + # Standard Dual Band + new24rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname24/statistics/rx_bytes)" + new24txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname24/statistics/tx_bytes)" + new5rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname5/statistics/rx_bytes)" + new5txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname5/statistics/tx_bytes)" + + # Tri or Quad Band 5GHz + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ] + then + new52rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname52/statistics/rx_bytes)" + new52txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname52/statistics/tx_bytes)" + fi + # Tri or Quad Band 6GHz + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ] + then + new6rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname6/statistics/rx_bytes)" + new6txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname6/statistics/tx_bytes)" + fi + if [ "$FourBandCustom56624" == "True" ] + then + new62rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname62/statistics/rx_bytes)" + new62txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname62/statistics/tx_bytes)" + fi + + # Network - LAN - Traffic + newlanrxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/br0/statistics/rx_bytes)" + newlantxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/br0/statistics/tx_bytes)" + + # Network - WAN - Traffic + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ] + then + if [ $WANOverride == "Auto" ]; then WANIFNAME=$(get_wan_setting ifname); else WANIFNAME=$WANOverride; fi + newwanrxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$WANIFNAME/statistics/rx_bytes)" + newwantxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$WANIFNAME/statistics/tx_bytes)" + fi + + # Grab total bytes VPN Traffic Measurement + if [ "$vpn1on" == "True" ]; then + newvpntxrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn1slot/status 2>/dev/null) + newvpnrxbytes="$(echo $newvpntxrxbytes | cut -d' ' -f1)" + newvpntxbytes="$(echo $newvpntxrxbytes | cut -d' ' -f2)" + if [ -z $newvpnrxbytes ]; then newvpnrxbytes=0; fi + if [ -z $newvpntxbytes ]; then newvpntxbytes=0; fi + + if [ $newvpnrxbytes -le 0 ]; then + newvpnrxbytes=0 + elif [ $newvpntxbytes -le 0 ]; then + newvpntxbytes=0 + fi + fi + + if [ "$vpn2on" == "True" ]; then + newvpn2txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn2slot/status 2>/dev/null) + newvpn2rxbytes="$(echo $newvpn2txrxbytes | cut -d' ' -f1)" + newvpn2txbytes="$(echo $newvpn2txrxbytes | cut -d' ' -f2)" + if [ -z $newvpn2rxbytes ]; then newvpn2rxbytes=0; fi + if [ -z $newvpn2txbytes ]; then newvpn2txbytes=0; fi + + if [ $newvpn2rxbytes -le 0 ]; then + newvpn2rxbytes=0 + elif [ $newvpn2txbytes -le 0 ]; then + newvpn2txbytes=0 + fi + fi + + if [ "$vpn3on" == "True" ]; then + newvpn3txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn3slot/status 2>/dev/null) + newvpn3rxbytes="$(echo $newvpn3txrxbytes | cut -d' ' -f1)" + newvpn3txbytes="$(echo $newvpn3txrxbytes | cut -d' ' -f2)" + if [ -z $newvpn3rxbytes ]; then newvpn3rxbytes=0; fi + if [ -z $newvpn3txbytes ]; then newvpn3txbytes=0; fi + + if [ $newvpn3rxbytes -le 0 ]; then + newvpn3rxbytes=0 + elif [ $newvpn3txbytes -le 0 ]; then + newvpn3txbytes=0 + fi + fi + + if [ "$vpn4on" == "True" ]; then + newvpn4txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn4slot/status 2>/dev/null) + newvpn4rxbytes="$(echo $newvpn4txrxbytes | cut -d' ' -f1)" + newvpn4txbytes="$(echo $newvpn4txrxbytes | cut -d' ' -f2)" + if [ -z $newvpn4rxbytes ]; then newvpn4rxbytes=0; fi + if [ -z $newvpn4txbytes ]; then newvpn4txbytes=0; fi + + if [ $newvpn4rxbytes -le 0 ]; then + newvpn4rxbytes=0 + elif [ $newvpn4txbytes -le 0 ]; then + newvpn4txbytes=0 + fi + fi + + if [ "$vpn5on" == "True" ]; then + newvpn5txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn5slot/status 2>/dev/null) + newvpn5rxbytes="$(echo $newvpn5txrxbytes | cut -d' ' -f1)" + newvpn5txbytes="$(echo $newvpn5txrxbytes | cut -d' ' -f2)" + if [ -z $newvpn5rxbytes ]; then newvpn5rxbytes=0; fi + if [ -z $newvpn5txbytes ]; then newvpn5txbytes=0; fi + + if [ $newvpn5rxbytes -le 0 ]; then + newvpn5rxbytes=0 + elif [ $newvpn5txbytes -le 0 ]; then + newvpn5txbytes=0 + fi + fi + + # Check the wireguard connections + if [ "$wg1on" == "True" ]; then + newwg1txrxbytes=$(wg show wgc1 transfer) + newwg1rxbytes="$(echo $newwg1txrxbytes | cut -d' ' -f3)" + newwg1txbytes="$(echo $newwg1txrxbytes | cut -d' ' -f2)" + if [ -z $newwg1rxbytes ] || [ $newwg1rxbytes -le 0 ]; then newwg1rxbytes=0; fi + if [ -z $newwg1txbytes ] || [ $newwg1txbytes -le 0 ]; then newwg1txbytes=0; fi + fi + + if [ "$wg2on" == "True" ]; then + newwg2txrxbytes=$(wg show wgc2 transfer) + newwg2rxbytes="$(echo $newwg2txrxbytes | cut -d' ' -f3)" + newwg2txbytes="$(echo $newwg2txrxbytes | cut -d' ' -f2)" + if [ -z $newwg2rxbytes ] || [ $newwg2rxbytes -le 0 ]; then newwg2rxbytes=0; fi + if [ -z $newwg2txbytes ] || [ $newwg2txbytes -le 0 ]; then newwg2txbytes=0; fi + fi + + if [ "$wg3on" == "True" ]; then + newwg3txrxbytes=$(wg show wgc3 transfer) + newwg3rxbytes="$(echo $newwg3txrxbytes | cut -d' ' -f3)" + newwg3txbytes="$(echo $newwg3txrxbytes | cut -d' ' -f2)" + if [ -z $newwg3rxbytes ] || [ $newwg3rxbytes -le 0 ]; then newwg3rxbytes=0; fi + if [ -z $newwg3txbytes ] || [ $newwg3txbytes -le 0 ]; then newwg3txbytes=0; fi + fi + + if [ "$wg4on" == "True" ]; then + newwg4txrxbytes=$(wg show wgc4 transfer) + newwg4rxbytes="$(echo $newwg4txrxbytes | cut -d' ' -f3)" + newwg4txbytes="$(echo $newwg4txrxbytes | cut -d' ' -f2)" + if [ -z $newwg4rxbytes ] || [ $newwg4rxbytes -le 0 ]; then newwg4rxbytes=0; fi + if [ -z $newwg4txbytes ] || [ $newwg4txbytes -le 0 ]; then newwg4txbytes=0; fi + fi + + if [ "$wg5on" == "True" ]; then + newwg5txrxbytes=$(wg show wgc5 transfer) + newwg5rxbytes="$(echo $newwg5txrxbytes | cut -d' ' -f3)" + newwg5txbytes="$(echo $newwg5txrxbytes | cut -d' ' -f2)" + if [ -z $newwg5rxbytes ] || [ $newwg5rxbytes -le 0 ]; then newwg5rxbytes=0; fi + if [ -z $newwg5txbytes ] || [ $newwg5txbytes -le 0 ]; then newwg5txbytes=0; fi + fi + + # Network - Traffic - Calculations to find the difference between old and new total bytes send/received and divided to give Megabits + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + diffwanrxbytes=$(awk -v new=$newwanrxbytes -v old=$oldwanrxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diffwantxbytes=$(awk -v new=$newwantxbytes -v old=$oldwantxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + diff24rxbytes=$(awk -v new=$new24rxbytes -v old=$old24rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diff24txbytes=$(awk -v new=$new24txbytes -v old=$old24txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diff5rxbytes=$(awk -v new=$new5rxbytes -v old=$old5rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diff5txbytes=$(awk -v new=$new5txbytes -v old=$old5txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + difflanrxbytes=$(awk -v new=$newlanrxbytes -v old=$oldlanrxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + difflantxbytes=$(awk -v new=$newlantxbytes -v old=$oldlantxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then + diff52rxbytes=$(awk -v new=$new52rxbytes -v old=$old52rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diff52txbytes=$(awk -v new=$new52txbytes -v old=$old52txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then + diff6rxbytes=$(awk -v new=$new6rxbytes -v old=$old6rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diff6txbytes=$(awk -v new=$new6txbytes -v old=$old6txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + if [ "$FourBandCustom56624" == "True" ]; then + diff62rxbytes=$(awk -v new=$new62rxbytes -v old=$old62rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diff62txbytes=$(awk -v new=$new62txbytes -v old=$old62txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + if [ "$vpn1on" == "True" ]; then + diffvpnrxbytes=$(awk -v new=$newvpnrxbytes -v old=$oldvpnrxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diffvpntxbytes=$(awk -v new=$newvpntxbytes -v old=$oldvpntxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + if [ "$vpn2on" == "True" ]; then + diffvpn2rxbytes=$(awk -v new=$newvpn2rxbytes -v old=$oldvpn2rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diffvpn2txbytes=$(awk -v new=$newvpn2txbytes -v old=$oldvpn2txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + if [ "$vpn3on" == "True" ]; then + diffvpn3rxbytes=$(awk -v new=$newvpn3rxbytes -v old=$oldvpn3rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diffvpn3txbytes=$(awk -v new=$newvpn3txbytes -v old=$oldvpn3txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + if [ "$vpn4on" == "True" ]; then + diffvpn4rxbytes=$(awk -v new=$newvpn4rxbytes -v old=$oldvpn4rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diffvpn4txbytes=$(awk -v new=$newvpn4txbytes -v old=$oldvpn4txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + if [ "$vpn5on" == "True" ]; then + diffvpn5rxbytes=$(awk -v new=$newvpn5rxbytes -v old=$oldvpn5rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diffvpn5txbytes=$(awk -v new=$newvpn5txbytes -v old=$oldvpn5txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + if [ "$wg1on" == "True" ]; then + diffwg1rxbytes=$(awk -v new=$newwg1rxbytes -v old=$oldwg1rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diffwg1txbytes=$(awk -v new=$newwg1txbytes -v old=$oldwg1txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + if [ "$wg2on" == "True" ]; then + diffwg2rxbytes=$(awk -v new=$newwg2rxbytes -v old=$oldwg2rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diffwg2txbytes=$(awk -v new=$newwg2txbytes -v old=$oldwg2txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + if [ "$wg3on" == "True" ]; then + diffwg3rxbytes=$(awk -v new=$newwg3rxbytes -v old=$oldwg3rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diffwg3txbytes=$(awk -v new=$newwg3txbytes -v old=$oldwg3txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + if [ "$wg4on" == "True" ]; then + diffwg4rxbytes=$(awk -v new=$newwg4rxbytes -v old=$oldwg4rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diffwg4txbytes=$(awk -v new=$newwg4txbytes -v old=$oldwg4txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + if [ "$wg5on" == "True" ]; then + diffwg5rxbytes=$(awk -v new=$newwg5rxbytes -v old=$oldwg5rxbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + diffwg5txbytes=$(awk -v new=$newwg5txbytes -v old=$oldwg5txbytes -v mb=125000 'BEGIN{printf "%.4f\n", (new-old)/mb}') + fi + + # Network - Traffic - Results are further divided by the timer/interval to give Megabits/sec + if [ "$WAN0AltModes" = "0" ] || [ "$OpsMode" = "1" ] + then + wanrxmbrate=$(awk -v rb=$diffwanrxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + wantxmbrate=$(awk -v tb=$diffwantxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + wanrxmbrate=0 + wantxmbrate=0 + fi + + w24rxmbrate=$(awk -v rb=$diff24rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + w24txmbrate=$(awk -v tb=$diff24txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + w5rxmbrate=$(awk -v rb=$diff5rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + w5txmbrate=$(awk -v tb=$diff5txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + lanrxmbrate=$(awk -v rb=$difflanrxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + lantxmbrate=$(awk -v tb=$difflantxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ] + then + w52rxmbrate=$(awk -v rb=$diff52rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + w52txmbrate=$(awk -v tb=$diff52txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + w52rxmbrate=0 + w52txmbrate=0 + fi + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ] + then + w6rxmbrate=$(awk -v rb=$diff6rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + w6txmbrate=$(awk -v tb=$diff6txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + w6rxmbrate=0 + w6txmbrate=0 + fi + if [ "$FourBandCustom56624" == "True" ] + then + w62rxmbrate=$(awk -v rb=$diff62rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + w62txmbrate=$(awk -v tb=$diff62txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + w62rxmbrate=0 + w62txmbrate=0 + fi + if [ "$vpn1on" == "True" ] + then + vpnrxmbrate=$(awk -v rb=$diffvpnrxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + vpntxmbrate=$(awk -v tb=$diffvpntxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + vpnrxmbrate=0 + vpntxmbrate=0 + fi + if [ "$vpn2on" == "True" ] + then + vpn2rxmbrate=$(awk -v rb=$diffvpn2rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + vpn2txmbrate=$(awk -v tb=$diffvpn2txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + vpn2rxmbrate=0 + vpn2txmbrate=0 + fi + if [ "$vpn3on" == "True" ] + then + vpn3rxmbrate=$(awk -v rb=$diffvpn3rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + vpn3txmbrate=$(awk -v tb=$diffvpn3txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + vpn3rxmbrate=0 + vpn3txmbrate=0 + fi + if [ "$vpn4on" == "True" ] + then + vpn4rxmbrate=$(awk -v rb=$diffvpn4rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + vpn4txmbrate=$(awk -v tb=$diffvpn4txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + vpn4rxmbrate=0 + vpn4txmbrate=0 + fi + if [ "$vpn5on" == "True" ] + then + vpn5rxmbrate=$(awk -v rb=$diffvpn5rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + vpn5txmbrate=$(awk -v tb=$diffvpn5txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + vpn5rxmbrate=0 + vpn5txmbrate=0 + fi + if [ "$wg1on" == "True" ] + then + wg1rxmbrate=$(awk -v rb=$diffwg1rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + wg1txmbrate=$(awk -v tb=$diffwg1txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + wg1rxmbrate=0 + wg1txmbrate=0 + fi + if [ "$wg2on" == "True" ] + then + wg2rxmbrate=$(awk -v rb=$diffwg2rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + wg2txmbrate=$(awk -v tb=$diffwg2txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + wg2rxmbrate=0 + wg2txmbrate=0 + fi + if [ "$wg3on" == "True" ] + then + wg3rxmbrate=$(awk -v rb=$diffwg3rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + wg3txmbrate=$(awk -v tb=$diffwg3txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + wg3rxmbrate=0 + wg3txmbrate=0 + fi + if [ "$wg4on" == "True" ] + then + wg4rxmbrate=$(awk -v rb=$diffwg4rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + wg4txmbrate=$(awk -v tb=$diffwg4txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + wg4rxmbrate=0 + wg4txmbrate=0 + fi + if [ "$wg5on" == "True" ] + then + wg5rxmbrate=$(awk -v rb=$diffwg5rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", rb/intv}' | cut -d . -f 1) + wg5txmbrate=$(awk -v tb=$diffwg5txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.2f\n", tb/intv}' | cut -d . -f 1) + else + wg5rxmbrate=0 + wg5txmbrate=0 + fi + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ] + then + wanrxmbratedisplay=$(awk -v rb=$diffwanrxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + wantxmbratedisplay=$(awk -v tb=$diffwantxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + fi + + w24rxmbratedisplay=$(awk -v rb=$diff24rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + w24txmbratedisplay=$(awk -v tb=$diff24txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + w5rxmbratedisplay=$(awk -v rb=$diff5rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + w5txmbratedisplay=$(awk -v tb=$diff5txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + lanrxmbratedisplay=$(awk -v rb=$difflanrxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + lantxmbratedisplay=$(awk -v tb=$difflantxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ] + then + w52rxmbratedisplay=$(awk -v rb=$diff52rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + w52txmbratedisplay=$(awk -v tb=$diff52txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + else + w52rxmbratedisplay="" + w52txmbratedisplay="" + fi + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ] + then + w6rxmbratedisplay=$(awk -v rb=$diff6rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + w6txmbratedisplay=$(awk -v tb=$diff6txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + else + w6rxmbratedisplay="" + w6txmbratedisplay="" + fi + if [ "$FourBandCustom56624" == "True" ] + then + w62rxmbratedisplay=$(awk -v rb=$diff62rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + w62txmbratedisplay=$(awk -v tb=$diff62txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + else + w62rxmbratedisplay="" + w62txmbratedisplay="" + fi + if [ "$vpn1on" == "True" ] + then + vpnrxmbratedisplay=$(awk -v rb=$diffvpnrxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + vpntxmbratedisplay=$(awk -v tb=$diffvpntxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + else + vpnrxmbratedisplay="" + vpntxmbratedisplay="" + fi + if [ "$vpn2on" == "True" ] + then + vpn2rxmbratedisplay=$(awk -v rb=$diffvpn2rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + vpn2txmbratedisplay=$(awk -v tb=$diffvpn2txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + else + vpn2rxmbratedisplay="" + vpn2txmbratedisplay="" + fi + if [ "$vpn3on" == "True" ] + then + vpn3rxmbratedisplay=$(awk -v rb=$diffvpn3rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + vpn3txmbratedisplay=$(awk -v tb=$diffvpn3txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + else + vpn3rxmbratedisplay="" + vpn3txmbratedisplay="" + fi + if [ "$vpn4on" == "True" ] + then + vpn4rxmbratedisplay=$(awk -v rb=$diffvpn4rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + vpn4txmbratedisplay=$(awk -v tb=$diffvpn4txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + else + vpn4rxmbratedisplay="" + vpn4txmbratedisplay="" + fi + if [ "$vpn5on" == "True" ] + then + vpn5rxmbratedisplay=$(awk -v rb=$diffvpn5rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + vpn5txmbratedisplay=$(awk -v tb=$diffvpn5txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + else + vpn5rxmbratedisplay="" + vpn5txmbratedisplay="" + fi + if [ "$wg1on" == "True" ] + then + wg1rxmbratedisplay=$(awk -v rb=$diffwg1rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + wg1txmbratedisplay=$(awk -v tb=$diffwg1txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + else + wg1rxmbratedisplay="" + wg1txmbratedisplay="" + fi + if [ "$wg2on" == "True" ] + then + wg2rxmbratedisplay=$(awk -v rb=$diffwg2rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + wg2txmbratedisplay=$(awk -v tb=$diffwg2txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + else + wg2rxmbratedisplay="" + wg2txmbratedisplay="" + fi + if [ "$wg3on" == "True" ] + then + wg3rxmbratedisplay=$(awk -v rb=$diffwg3rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + wg3txmbratedisplay=$(awk -v tb=$diffwg3txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + else + wg3rxmbratedisplay="" + wg3txmbratedisplay="" + fi + if [ "$wg4on" == "True" ] + then + wg4rxmbratedisplay=$(awk -v rb=$diffwg4rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + wg4txmbratedisplay=$(awk -v tb=$diffwg4txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + else + wg4rxmbratedisplay="" + wg4txmbratedisplay="" + fi + if [ "$wg5on" == "True" ] + then + wg5rxmbratedisplay=$(awk -v rb=$diffwg5rxbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", rb/intv}') + wg5txmbratedisplay=$(awk -v tb=$diffwg5txbytes -v intv=$RM_ELAPSED_TIME 'BEGIN{printf "%0.1f\n", tb/intv}') + else + wg5rxmbratedisplay="" + wg5txmbratedisplay="" + fi + + # Uptime calc # + uptimeStr="$(awk '{printf("%3dd %02dh %02dm %02ds\n",($1/60/60/24),($1/60/60%24),($1/60%60),($1%60))}' /proc/uptime)" + +} + +# ------------------------------------------------------------------------------------------------------------------------- + +# This function displays the stats UI for page 1 +DisplayPage1() +{ + + clear + if [ "$UpdateNotify" != "0" ]; then + echo -e "$UpdateNotify${CClear}" + fi + showheader + echo "" + echo -e "${InvDkGray}${CWhite} CPU ${CClear}" + echo "" + echo -e "${InvGreen} ${CClear} ${CWhite}Uptime ${CDkGray}[ ${CWhite}$uptimeStr${CDkGray} ]${CClear}" + echo -e "${InvGreen} ${CClear} ${CWhite}CPU Load ${CDkGray}[ ${CGreen}1m: ${CWhite}$cpuload1m ${CGreen}5m: ${CWhite}$cpuload5m ${CGreen}15m: ${CWhite}$cpuload15m${CDkGray} ]${CClear}" + preparebar 79 "|" + progressbar $oldcpuusr1 100 " CPU User " "%%" "Standard" $olddisplaycpuusr1 + echo "" + preparebar 79 "|" + progressbar $oldcpusys1 100 " CPU System" "%%" "Standard" $olddisplaycpusys1 + echo "" + preparebar 79 "|" + progressbar $oldcpunice1 100 " CPU Nice " "%%" "Standard" $olddisplaycpunice1 + echo "" + preparebar 79 "|" + progressbar $oldcpuidle1 100 " CPU Idle " "%%" "Reverse" $olddisplaycpuidle1 + echo "" + preparebar 79 "|" + progressbar $oldcpuirq1 100 " CPU IRQ " "%%" "Standard" $olddisplaycpuirq1 + echo "" + preparebar 79 "|" + converttemps $oldF_cputemp + progressbar $currenttemp $currentrange " CPU Temp " $TempUnits "CPU" $currenttemp $currentrange + echo "" + echo "" + echo -e "${InvDkGray}${CWhite} Memory ${CClear}" + echo "" + echo -en "${InvGreen} ${CClear} ${CWhite}Mem Total ${CDkGray}[ ${CWhite}" + printf "%-7s" "$totalphysmem MB" + echo -e "${CDkGray} ]${CClear}" + preparebar 79 "|" + progressbar $oldmemused2 $oldtotalmemory " Mem Used " "MB" "Standard" + echo "" + preparebar 79 "|" + progressbar $oldmemfree2 $oldtotalmemory " Mem Free " "MB" "Reverse" + echo "" + preparebar 79 "|" + progressbar $oldmemshrd2 $oldtotalmemory " Mem Shared" "MB" "Standard" + echo "" + preparebar 79 "|" + progressbar $oldmembuff2 $oldtotalmemory " Mem Buffer" "MB" "Standard" + echo "" + preparebar 79 "|" + progressbar $oldmemcach2 $oldtotalmemory " Mem Cache " "MB" "Standard" + echo "" + preparebar 79 "|" + progressbar $oldnvramused $oldtotalnvram " NVRAM Used" "B" "Standard" + echo "" + echo "" + echo -e "${InvDkGray}${CWhite} Disk ${CClear}" + echo "" + echo -en "${InvGreen} ${CClear} ${CWhite}Swap Size ${CDkGray}[ ${CWhite}" + printf "%-8s" "$swaptotal MB" + echo -e "${CDkGray} ]${CClear}" + preparebar 79 "|" + progressbar $oldswapused $oldswaptotal " Swap Used " "MB" "Standard" + echo "" + preparebar 79 "|" + progressbar $oldjffsused $oldjffstotal " JFFS Used " "MB" "Standard" + + #Disk - SD devices + if [ -s /jffs/addons/rtrmon.d/sdresult.txt ] + then + sdcnt=$(cat /jffs/addons/rtrmon.d/sdresult.txt | wc -l) >/dev/null 2>&1 + if [ -z "$sdcnt" ] || [ $sdcnt -lt 1 ]; then + sdcnt=0 + fi + else + sdcnt=0 + fi + + CNT=0 + while [ "$CNT" -lt "$sdcnt" ] # Loop through number of /dev/sd*'s # + do + CNT="$((CNT+1))" + dfresults="$(sed -n "${CNT}p" /jffs/addons/rtrmon.d/sdresult.txt)" + if [ -z "$dfresults" ]; then break; fi + sdname="$(echo $dfresults | awk '{print $1}')" + sdtotal="$(echo $dfresults | awk '{print $2}')" + sdused="$(echo $dfresults | awk '{print $3}')" + + sdtotal=$(echo "$sdtotal 1048576" | awk '{print $1/$2}' | cut -d . -f 1) + sdused=$(echo "$sdused 1048576" | awk '{print $1/$2}' | cut -d . -f 1) + if [ $sdtotal == "0" ]; then sdtotal=1; fi + if [ $sdused == "0" ]; then sdused=1; fi + sdnameformat=$(printf "%-10s" $sdname) + + echo "" + preparebar 79 "|" + progressbar $sdused $sdtotal " $sdnameformat" "GB" "Standard" + done +} + +# ------------------------------------------------------------------------------------------------------------------------- + +# This function displays the stats UI for page 2 +DisplayPage2() +{ + clear + if [ "$UpdateNotify" != "0" ]; then + echo -e "$UpdateNotify${CClear}" + fi + showheader + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + echo "" + echo -e "${InvDkGray}${CWhite} WAN ${CClear}" + echo "" + if [ "$ScreenshotMode" == "1" ]; then + oldwan0ip="1.2.3.4" #demo + oldwanip6="abc1:23de::f456:ghi7:89jk:l0mn:opqr" #demo + oldvpn1ip="2.3.4.5" #demo + oldvpn2ip="3.4.5.6" #demo + oldvpn3ip="4.5.6.7" #demo + oldvpn4ip="5.6.7.8" #demo + oldvpn5ip="6.7.8.9" #demo + oldwg1ip="2.3.4.5" #demo + oldwg2ip="3.4.5.6" #demo + oldwg3ip="4.5.6.7" #demo + oldwg4ip="5.6.7.8" #demo + oldwg5ip="6.7.8.9" #demo + oldvpn1city="Rivendell" #demo + oldvpn2city="Mordor" #demo + oldvpn3city="Minas Tirith" #demo + oldvpn4city="Edoras" #demo + oldvpn5city="Aglarond" #demo + oldwg1city="Rivendell" #demo + oldwg2city="Mordor" #demo + oldwg3city="Minas Tirith" #demo + oldwg4city="Edoras" #demo + oldwg5city="Aglarond" #demo + fi + echo -en "${InvGreen} ${CClear} ${CWhite}WAN 0/1 IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldwan0ip//./ } + echo -en " / " + printf '%03d.%03d.%03d.%03d' ${oldwan1ip//./ } + echo -en "${CDkGray} ] ${CWhite} DNS ${CDkGray}[ ${CWhite}" + if [ $olddns1ip = "0.0.0.0" ]; then printf "000.000.000.000"; else printf '%03d.%03d.%03d.%03d' ${olddns1ip//./ }; fi + echo -en " / " + if [ $olddns2ip = "0.0.0.0" ]; then printf "000.000.000.000"; else printf '%03d.%03d.%03d.%03d' ${olddns2ip//./ }; fi + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}IFace: $WANIFNAME${CClear}" + if [ ! -z $oldwanip6 ]; then echo -e "${InvGreen} ${CClear} ${CWhite}WAN 0/1 I6 ${CDkGray}[ ${CWhite}$oldwanip6${CClear}"; fi + preparebar 79 "|" + progressbar $oldwanrxmbrate $MaxSpeedInet " Avg WAN RX" "Mbps" "Standard" $oldwanrxmbratedisplay $MaxSpeedInet + echo "" + preparebar 79 "|" + progressbar $oldwantxmbrate $MaxSpeedInetUL " Avg WAN TX" "Mbps" "Standard" $oldwantxmbratedisplay $MaxSpeedInetUL + echo "" + fi + echo "" + echo -e "${InvDkGray}${CWhite} LAN ${CClear}" + echo "" + echo -en "${InvGreen} ${CClear}${CWhite} BR0 LAN IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldlanip//./ } + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}IFace: br0${CClear}" + if [ ! -z $oldlanip6 ]; then echo -e "${InvGreen} ${CClear} ${CWhite}BR0 LAN I6 ${CDkGray}[ ${CWhite}$oldlanip6${CClear}"; fi + + preparebar 79 "|" + progressbar $oldlanrxmbrate $MaxSpeedLAN " Avg LAN RX" "Mbps" "Standard" $oldlanrxmbratedisplay $MaxSpeedLAN + echo "" + preparebar 79 "|" + if [ ${oldlantxmbrate%.*} -lt 0 ]; then oldlantxmbrate=0; oldlantxmbratedisplay=0; fi + progressbar $oldlantxmbrate $MaxSpeedLAN " Avg LAN TX" "Mbps" "Standard" $oldlantxmbratedisplay $MaxSpeedLAN + + if [ "$vpn1on" == "True" ]; then + echo "" + echo "" + echo -e "${InvDkGray}${CWhite} OVPN$vpn1slot ${CClear}" + echo "" + if [ "$oldvpn1city" == "Private Network" ]; then + echo -en "${InvGreen} ${CClear}${CWhite} PRV VPN IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldvpn1ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldvpn1city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn1slot${CClear}" + else + echo -en "${InvGreen} ${CClear}${CWhite} PUB VPN IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldvpn1ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldvpn1city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn1slot${CClear}" + fi + if [ ${oldvpntxmbrate%.*} -lt 0 ]; then oldvpntxmbrate=0; oldvpntxmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldvpntxmbrate $MaxSpeedInet " Avg VPN RX" "Mbps" "Standard" $oldvpntxmbratedisplay $MaxSpeedInet + echo "" + if [ ${oldvpnrxmbrate%.*} -lt 0 ]; then oldvpnrxmbrate=0; oldvpnrxmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldvpnrxmbrate $MaxSpeedInetUL " Avg VPN TX" "Mbps" "Standard" $oldvpnrxmbratedisplay $MaxSpeedInetUL + fi + + if [ "$vpn2on" == "True" ]; then + echo "" + echo "" + echo -e "${InvDkGray}${CWhite} OVPN$vpn2slot ${CClear}" + echo "" + if [ "$oldvpn2city" == "Private Network" ]; then + echo -en "${InvGreen} ${CClear}${CWhite} PRV VPN IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldvpn2ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldvpn2city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn2slot${CClear}" + else + echo -en "${InvGreen} ${CClear}${CWhite} PUB VPN IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldvpn2ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldvpn2city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn2slot${CClear}" + fi + if [ ${oldvpn2txmbrate%.*} -lt 0 ]; then oldvpn2txmbrate=0; oldvpn2txmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldvpn2txmbrate $MaxSpeedInet " Avg VPN RX" "Mbps" "Standard" $oldvpn2txmbratedisplay $MaxSpeedInet + echo "" + if [ ${oldvpn2rxmbrate%.*} -lt 0 ]; then oldvpn2rxmbrate=0; oldvpn2rxmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldvpn2rxmbrate $MaxSpeedInetUL " Avg VPN TX" "Mbps" "Standard" $oldvpn2rxmbratedisplay $MaxSpeedInetUL + fi + + if [ "$vpn3on" == "True" ]; then + echo "" + echo "" + echo -e "${InvDkGray}${CWhite} OVPN$vpn3slot ${CClear}" + echo "" + if [ "$oldvpn3city" == "Private Network" ]; then + echo -en "${InvGreen} ${CClear}${CWhite} PRV VPN IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldvpn3ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldvpn3city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn3slot${CClear}" + else + echo -en "${InvGreen} ${CClear}${CWhite} PUB VPN IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldvpn3ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldvpn3city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn3slot${CClear}" + fi + if [ ${oldvpn3txmbrate%.*} -lt 0 ]; then oldvpn3txmbrate=0; oldvpn3txmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldvpn3txmbrate $MaxSpeedInet " Avg VPN RX" "Mbps" "Standard" $oldvpn3txmbratedisplay $MaxSpeedInet + echo "" + if [ ${oldvpn3rxmbrate%.*} -lt 0 ]; then oldvpn3rxmbrate=0; oldvpn3rxmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldvpn3rxmbrate $MaxSpeedInetUL " Avg VPN TX" "Mbps" "Standard" $oldvpn3rxmbratedisplay $MaxSpeedInetUL + fi + + if [ "$vpn4on" == "True" ]; then + echo "" + echo "" + echo -e "${InvDkGray}${CWhite} OVPN$vpn4slot ${CClear}" + echo "" + if [ "$oldvpn4city" == "Private Network" ]; then + echo -en "${InvGreen} ${CClear}${CWhite} PRV VPN IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldvpn4ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldvpn4city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn4slot${CClear}" + else + echo -en "${InvGreen} ${CClear}${CWhite} PUB VPN IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldvpn4ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldvpn4city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn4slot${CClear}" + fi + if [ ${oldvpn4txmbrate%.*} -lt 0 ]; then oldvpn4txmbrate=0; oldvpn4txmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldvpn4txmbrate $MaxSpeedInet " Avg VPN RX" "Mbps" "Standard" $oldvpn4txmbratedisplay $MaxSpeedInet + echo "" + if [ ${oldvpn4rxmbrate%.*} -lt 0 ]; then oldvpn4rxmbrate=0; oldvpn4rxmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldvpn4rxmbrate $MaxSpeedInetUL " Avg VPN TX" "Mbps" "Standard" $oldvpn4rxmbratedisplay $MaxSpeedInetUL + fi + + if [ "$vpn5on" == "True" ]; then + echo "" + echo "" + echo -e "${InvDkGray}${CWhite} OVPN$vpn5slot ${CClear}" + echo "" + if [ "$oldvpn5city" == "Private Network" ]; then + echo -en "${InvGreen} ${CClear}${CWhite} PRV VPN IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldvpn5ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldvpn5city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn5slot${CClear}" + else + echo -en "${InvGreen} ${CClear}${CWhite} PUB VPN IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldvpn5ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldvpn5city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn5slot${CClear}" + fi + if [ ${oldvpn5txmbrate%.*} -lt 0 ]; then oldvpn5txmbrate=0; oldvpn5txmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldvpn5txmbrate $MaxSpeedInet " Avg VPN RX" "Mbps" "Standard" $oldvpn5txmbratedisplay $MaxSpeedInet + echo "" + if [ ${oldvpn5rxmbrate%.*} -lt 0 ]; then oldvpn5rxmbrate=0; oldvpn5rxmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldvpn5rxmbrate $MaxSpeedInetUL " Avg VPN TX" "Mbps" "Standard" $oldvpn5rxmbratedisplay $MaxSpeedInetUL + fi + + if [ "$wg1on" == "True" ]; then + echo "" + echo "" + echo -e "${InvDkGray}${CWhite} WG$wg1slot ${CClear}" + echo "" + if [ "$oldwg1city" == "Private Network" ]; then + echo -en "${InvGreen} ${CClear}${CWhite} PRV WG IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldwg1ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldwg1city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg1slot${CClear}" + else + echo -en "${InvGreen} ${CClear}${CWhite} PUB WG IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldwg1ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldwg1city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg1slot${CClear}" + fi + if [ ${oldwg1txmbrate%.*} -lt 0 ]; then oldwg1txmbrate=0; oldwg1txmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldwg1txmbrate $MaxSpeedInet " Avg WG RX " "Mbps" "Standard" $oldwg1txmbratedisplay $MaxSpeedInet + echo "" + if [ ${oldwg1rxmbrate%.*} -lt 0 ]; then oldwg1rxmbrate=0; oldwg1rxmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldwg1rxmbrate $MaxSpeedInetUL " Avg WG TX " "Mbps" "Standard" $oldwg1rxmbratedisplay $MaxSpeedInetUL + fi + + if [ "$wg2on" == "True" ]; then + echo "" + echo "" + echo -e "${InvDkGray}${CWhite} WG$wg2slot ${CClear}" + echo "" + if [ "$oldwg2city" == "Private Network" ]; then + echo -en "${InvGreen} ${CClear}${CWhite} PRV WG IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldwg2ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldwg2city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg2slot${CClear}" + else + echo -en "${InvGreen} ${CClear}${CWhite} PUB WG IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldwg2ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldwg2city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg2slot${CClear}" + fi + if [ ${oldwg2txmbrate%.*} -lt 0 ]; then oldwg2txmbrate=0; oldwg2txmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldwg2txmbrate $MaxSpeedInet " Avg WG RX " "Mbps" "Standard" $oldwg2txmbratedisplay $MaxSpeedInet + echo "" + if [ ${oldwg2rxmbrate%.*} -lt 0 ]; then oldwg2rxmbrate=0; oldwg2rxmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldwg2rxmbrate $MaxSpeedInetUL " Avg WG TX " "Mbps" "Standard" $oldwg2rxmbratedisplay $MaxSpeedInetUL + fi + + if [ "$wg3on" == "True" ]; then + echo "" + echo "" + echo -e "${InvDkGray}${CWhite} WG$wg3slot ${CClear}" + echo "" + if [ "$oldwg3city" == "Private Network" ]; then + echo -en "${InvGreen} ${CClear}${CWhite} PRV WG IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldwg3ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldwg3city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg3slot${CClear}" + else + echo -en "${InvGreen} ${CClear}${CWhite} PUB WG IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldwg3ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldwg3city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg3slot${CClear}" + fi + if [ ${oldwg3txmbrate%.*} -lt 0 ]; then oldwg3txmbrate=0; oldwg3txmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldwg3txmbrate $MaxSpeedInet " Avg WG RX " "Mbps" "Standard" $oldwg3txmbratedisplay $MaxSpeedInet + echo "" + if [ ${oldwg3rxmbrate%.*} -lt 0 ]; then oldwg3rxmbrate=0; oldwg3rxmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldwg3rxmbrate $MaxSpeedInetUL " Avg WG TX " "Mbps" "Standard" $oldwg3rxmbratedisplay $MaxSpeedInetUL + fi + + if [ "$wg4on" == "True" ]; then + echo "" + echo "" + echo -e "${InvDkGray}${CWhite} WG$wg4slot ${CClear}" + echo "" + if [ "$oldwg4city" == "Private Network" ]; then + echo -en "${InvGreen} ${CClear}${CWhite} PRV WG IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldwg4ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldwg4city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg4slot${CClear}" + else + echo -en "${InvGreen} ${CClear}${CWhite} PUB WG IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldwg4ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldwg4city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg4slot${CClear}" + fi + if [ ${oldwg4txmbrate%.*} -lt 0 ]; then oldwg4txmbrate=0; oldwg4txmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldwg4txmbrate $MaxSpeedInet " Avg WG RX " "Mbps" "Standard" $oldwg4txmbratedisplay $MaxSpeedInet + echo "" + if [ ${oldwg4rxmbrate%.*} -lt 0 ]; then oldwg4rxmbrate=0; oldwg4rxmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldwg4rxmbrate $MaxSpeedInetUL " Avg WG TX " "Mbps" "Standard" $oldwg4rxmbratedisplay $MaxSpeedInetUL + fi + + if [ "$wg5on" == "True" ]; then + echo "" + echo "" + echo -e "${InvDkGray}${CWhite} WG$wg5slot ${CClear}" + echo "" + if [ "$oldwg5city" == "Private Network" ]; then + echo -en "${InvGreen} ${CClear}${CWhite} PRV WG IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldwg5ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldwg5city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg5slot${CClear}" + else + echo -en "${InvGreen} ${CClear}${CWhite} PUB WG IP ${CDkGray}[ ${CWhite}" + printf '%03d.%03d.%03d.%03d' ${oldwg5ip//./ } + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + + printf "%-33s" "$oldwg5city" + + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg5slot${CClear}" + fi + if [ ${oldwg5txmbrate%.*} -lt 0 ]; then oldwg5txmbrate=0; oldwg5txmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldwg5txmbrate $MaxSpeedInet " Avg WG RX " "Mbps" "Standard" $oldwg5txmbratedisplay $MaxSpeedInet + echo "" + if [ ${oldwg5rxmbrate%.*} -lt 0 ]; then oldwg5rxmbrate=0; oldwg5rxmbratedisplay=0; fi + preparebar 79 "|" + progressbar $oldwg5rxmbrate $MaxSpeedInetUL " Avg WG TX " "Mbps" "Standard" $oldwg5rxmbratedisplay $MaxSpeedInetUL + fi + +} + +# ------------------------------------------------------------------------------------------------------------------------- + +# This function displays the stats UI for page 3 +DisplayPage3() +{ + clear + if [ "$UpdateNotify" != "0" ]; then + echo -e "$UpdateNotify${CClear}" + fi + showheader + # Per @Stephen Harrington's sugguestion, check NVRAM to see if Wifi is turned on, else mark them as disabled + if [ "$FourBandCustom55624" == "True" ]; then + if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then + MaxSpeed52GhzNow=0 + else + MaxSpeed52GhzNow=$MaxSpeed5Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then + MaxSpeed6GhzNow=0 + else + MaxSpeed6GhzNow=$MaxSpeed6Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl3_radio) -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + elif [ "$FourBandCustom56624" == "True" ]; then + if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then + MaxSpeed6GhzNow=0 + else + MaxSpeed6GhzNow=$MaxSpeed6Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then + MaxSpeed62GhzNow=0 + else + MaxSpeed62GhzNow=$MaxSpeed6Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl3_radio) -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + elif [ "$ThreeBand2456" == "True" ]; then + if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then + MaxSpeed6GhzNow=0 + else + MaxSpeed6GhzNow=$MaxSpeed6Ghz + fi + elif [ "$ThreeBand2455" == "True" ]; then + if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then + MaxSpeed52GhzNow=0 + else + MaxSpeed52GhzNow=$MaxSpeed5Ghz + fi + else + if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + fi + + echo "" + echo -e "${InvDkGray}${CWhite} WiFi ${CClear}" + echo "" + if [ "$MaxSpeed24GhzNow" != "0" ]; then + if [ "$w24updown" == "UP" ]; then + echo -e "${InvGreen} ${CClear} ${CWhite}2.4GHz ${CDkGray}[ ${CWhite}Enabled - $w24udsched - UP ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname24${CClear}" + else + echo -e "${InvGreen} ${CClear} ${CWhite}2.4GHz ${CDkGray}[ ${CWhite}Enabled - $w24udsched - DOWN ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname24${CClear}" + fi + preparebar 79 "|" + progressbar $oldw24rxmbrate $MaxSpeed24GhzNow " Avg 24G RX" "Mbps" "Standard" $oldw24rxmbratedisplay $MaxSpeed24GhzNow + echo "" + preparebar 79 "|" + progressbar $oldw24txmbrate $MaxSpeed24GhzNow " Avg 24G TX" "Mbps" "Standard" $oldw24txmbratedisplay $MaxSpeed24GhzNow + echo "" + preparebar 79 "|" + converttemps $oldw24temp + progressbar $currenttemp $currentrange " 2.4G Temp " $TempUnits "Standard" $currenttemp $currentrange + else + echo -e "${InvRed} ${CClear}${CWhite} 2.4GHz ${CDkGray}[ ${CRed}Disabled ${CDkGray}]${CClear}" + fi + if [ "$MaxSpeed5GhzNow" != "0" ]; then + echo "" + echo "" + if [ "$w5updown" == "UP" ]; then + echo -e "${InvGreen} ${CClear} ${CWhite}5.0GHz ${CDkGray}[ ${CWhite}Enabled - $w5udsched - UP ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname5${CClear}" + else + echo -e "${InvGreen} ${CClear} ${CWhite}5.0GHz ${CDkGray}[ ${CWhite}Enabled - $w5udsched - DOWN ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname5${CClear}" + fi + preparebar 79 "|" + progressbar $oldw5rxmbrate $MaxSpeed5GhzNow " Avg 5G1 RX" "Mbps" "Standard" $oldw5rxmbratedisplay $MaxSpeed5GhzNow + echo "" + preparebar 79 "|" + progressbar $oldw5txmbrate $MaxSpeed5GhzNow " Avg 5G1 TX" "Mbps" "Standard" $oldw5txmbratedisplay $MaxSpeed5GhzNow + echo "" + preparebar 79 "|" + converttemps $oldw5temp + progressbar $currenttemp $currentrange " 5G-1 Temp " $TempUnits "Standard" $currenttemp $currentrange + else + echo "" + echo "" + echo -e "${InvRed} ${CClear}${CWhite} 5.0GHz ${CDkGray}[ ${CRed}Disabled ${CDkGray}]${CClear}" + fi + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then + if [ "$MaxSpeed52GhzNow" != "0" ]; then + echo "" + echo "" + if [ "$w52updown" == "UP" ]; then + echo -e "${InvGreen} ${CClear} ${CWhite}5.0GHz (2) ${CDkGray}[ ${CWhite}Enabled - $w52udsched - UP ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname52${CClear}" + else + echo -e "${InvGreen} ${CClear} ${CWhite}5.0GHz (2) ${CDkGray}[ ${CWhite}Enabled - $w52udsched - DOWN ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname52${CClear}" + fi + preparebar 79 "|" + progressbar $oldw52rxmbrate $MaxSpeed5GhzNow " Avg 5G2 RX" "Mbps" "Standard" $oldw52rxmbratedisplay $MaxSpeed5GhzNow + echo "" + preparebar 79 "|" + progressbar $oldw52txmbrate $MaxSpeed5GhzNow " Avg 5G2 TX" "Mbps" "Standard" $oldw52txmbratedisplay $MaxSpeed5GhzNow + echo "" + preparebar 79 "|" + converttemps $oldw52temp + progressbar $currenttemp $currentrange " 5G-2 Temp " $TempUnits "Standard" $currenttemp $currentrange + else + echo "" + echo "" + echo -e "${InvRed} ${CClear}${CWhite} 5.0GHz (2) ${CDkGray}[ ${CRed}Disabled ${CDkGray}]${CClear}" + fi + fi + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then + if [ "$MaxSpeed6GhzNow" != "0" ]; then + echo "" + echo "" + if [ "$w6updown" == "UP" ]; then + echo -e "${InvGreen} ${CClear} ${CWhite}6.0GHz ${CDkGray}[ ${CWhite}Enabled - $w6udsched - UP ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname6${CClear}" + else + echo -e "${InvGreen} ${CClear} ${CWhite}6.0GHz ${CDkGray}[ ${CWhite}Enabled - $w6udsched - DOWN ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname6${CClear}" + fi + preparebar 79 "|" + progressbar $oldw6rxmbrate $MaxSpeed6GhzNow " Avg 60G RX" "Mbps" "Standard" $oldw6rxmbratedisplay $MaxSpeed6GhzNow + echo "" + preparebar 79 "|" + progressbar $oldw6txmbrate $MaxSpeed6GhzNow " Avg 60G TX" "Mbps" "Standard" $oldw6txmbratedisplay $MaxSpeed6GhzNow + echo "" + preparebar 79 "|" + converttemps $oldw6temp + progressbar $currenttemp $currentrange " 6.0G Temp " $TempUnits "Standard" $currenttemp $currentrange + else + echo "" + echo "" + echo -e "${InvRed} ${CClear}${CWhite} 6.0GHz ${CDkGray}[ ${CRed}Disabled ${CDkGray}]${CClear}" + fi + fi + if [ "$FourBandCustom56624" == "True" ]; then + if [ "$MaxSpeed62GhzNow" != "0" ]; then + echo "" + echo "" + if [ "$w62updown" == "UP" ]; then + echo -e "${InvGreen} ${CClear} ${CWhite}6.0GHz (2) ${CDkGray}[ ${CWhite}Enabled - $w62udsched - UP ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname62${CClear}" + else + echo -e "${InvGreen} ${CClear} ${CWhite}6.0GHz (2) ${CDkGray}[ ${CWhite}Enabled - $w62udsched - DOWN ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname62${CClear}" + fi + preparebar 79 "|" + progressbar $oldw62rxmbrate $MaxSpeed62GhzNow " Avg 6G2 RX" "Mbps" "Standard" $oldw62rxmbratedisplay $MaxSpeed62GhzNow + echo "" + preparebar 79 "|" + progressbar $oldw62txmbrate $MaxSpeed62GhzNow " Avg 6G2 TX" "Mbps" "Standard" $oldw62txmbratedisplay $MaxSpeed62GhzNow + echo "" + preparebar 79 "|" + converttemps $oldw62temp + progressbar $currenttemp $currentrange " 6G-2 Temp " $TempUnits "Standard" $currenttemp $currentrange + else + echo "" + echo "" + echo -e "${InvRed} ${CClear}${CWhite} 6.0GHz (2) ${CDkGray}[ ${CRed}Disabled ${CDkGray}]${CClear}" + fi + fi +} + +# ------------------------------------------------------------------------------------------------------------------------- + +# This function displays the stats UI for page 4 +DisplayPage4() +{ + clear + if [ "$UpdateNotify" != "0" ]; then + echo -e "$UpdateNotify${CClear}" + fi + showheader + echo "" + echo -e "${InvDkGray}${CWhite} Speedtest ${CClear}" + + if [ "$QueueVPNSlot1" = "1" ]; then + DisplaySpdtst 1 + elif [ "$QueueVPNSlot2" = "1" ]; then + DisplaySpdtst 2 + elif [ "$QueueVPNSlot3" = "1" ]; then + DisplaySpdtst 3 + elif [ "$QueueVPNSlot4" = "1" ]; then + DisplaySpdtst 4 + elif [ "$QueueVPNSlot5" = "1" ]; then + DisplaySpdtst 5 + elif [ "$QueueWGSlot1" = "1" ]; then + DisplaySpdtst 6 + elif [ "$QueueWGSlot2" = "1" ]; then + DisplaySpdtst 7 + elif [ "$QueueWGSlot3" = "1" ]; then + DisplaySpdtst 8 + elif [ "$QueueWGSlot4" = "1" ]; then + DisplaySpdtst 9 + elif [ "$QueueWGSlot5" = "1" ]; then + DisplaySpdtst 0 + else + DisplaySpdtst + fi +} + +# ------------------------------------------------------------------------------------------------------------------------- + +# This function displays speedtest results and runs new speedtest +# $1 = VPN Slot + +DisplaySpdtst() +{ + if [ "$Speedtst" = "0" ] || [ ! -f $OOKLAPATH ]; then + echo -e "${InvGreen} ${CClear}" + echo -e "${InvRed} ${CClear} ${CRed}[Ookla Speedtest is not installed/configured]${CClear}" + echo -e "${InvRed} ${CClear} ${CRed}[Please use the configuration menu to enable functionality]${CClear}" + sleep 3 + return + fi + + # Check to see if previous results are available to display + if [ -f "$SPDRESPATH" ]; then + source "$SPDRESPATH" + else + SpdDate="No previous results found" + SpdServer="Press 'I' to Initiate a Speedtest" + SpdLatency=0 + SpdJitter=0 + SpdPacketLoss=0 + SpdDownload=0 + SpdUpload=0 + fi + + echo -e "${InvGreen} ${CClear}" + + if [ "$QueueSpdTest" = "1" ] + then + #run speedtest and save Results + printf "\r${InvGreen} ${CClear} ${CGreen}[Initializing WAN Speedtest]" + #printf "${CGreen}\r[Initializing WAN Speedtest]" + if [ $spdtestsvrID == "0" ]; then + speed="$(/jffs/addons/rtrmon.d/speedtest --format=csv --interface=$WANIFNAME --accept-license --accept-gdpr 2>&1)" + else + speed="$(/jffs/addons/rtrmon.d/speedtest --format=csv --interface=$WANIFNAME --server-id=$spdtestsvrID --accept-license --accept-gdpr 2>&1)" + fi + SpdDate=$(date) + SpdServer=$(echo $speed | awk -F '","' 'NR==1 {print $1}' | sed -e 's/^"//' -e 's/"$//' -e 's/[^a-zA-Z0-9 -]//g') + SpdLatency=$(echo $speed | awk -F '","' 'NR==1 {print $3}' | sed -e 's/^"//' -e 's/"$//') + SpdLatencyLo=$(echo $speed | awk -F '","' 'NR==1 {print $20}' | sed -e 's/^"//' -e 's/"$//') + SpdLatencyHi=$(echo $speed | awk -F '","' 'NR==1 {print $21}' | sed -e 's/^"//' -e 's/"$//') + SpdJitter=$(echo $speed | awk -F '","' 'NR==1 {print $4}' | sed -e 's/^"//' -e 's/"$//') + SpdPacketLoss=$(echo $speed | awk -F '","' 'NR==1 {print $5}' | sed -e 's/^"//' -e 's/"$//') + SpdDownload=$(echo $speed | awk -F '","' 'NR==1 {print $6}' | sed -e 's/^"//' -e 's/"$//') + SpdUpload=$(echo $speed | awk -F '","' 'NR==1 {print $7}' | sed -e 's/^"//' -e 's/"$//') + SpdDLLatency=$(echo $speed | awk -F '","' 'NR==1 {print $12}' | sed -e 's/^"//' -e 's/"$//') + SpdDLLatencyJt=$(echo $speed | awk -F '","' 'NR==1 {print $13}' | sed -e 's/^"//' -e 's/"$//') + SpdDLLatencyLo=$(echo $speed | awk -F '","' 'NR==1 {print $14}' | sed -e 's/^"//' -e 's/"$//') + SpdDLLatencyHi=$(echo $speed | awk -F '","' 'NR==1 {print $15}' | sed -e 's/^"//' -e 's/"$//') + SpdULLatency=$(echo $speed | awk -F '","' 'NR==1 {print $16}' | sed -e 's/^"//' -e 's/"$//') + SpdULLatencyJt=$(echo $speed | awk -F '","' 'NR==1 {print $17}' | sed -e 's/^"//' -e 's/"$//') + SpdULLatencyLo=$(echo $speed | awk -F '","' 'NR==1 {print $18}' | sed -e 's/^"//' -e 's/"$//') + SpdULLatencyHi=$(echo $speed | awk -F '","' 'NR==1 {print $19}' | sed -e 's/^"//' -e 's/"$//') + + if [ $SpdDownload -eq 0 ]; then SpdDownload=1; fi + if [ $SpdUpload -eq 0 ]; then SpdUpload=1; fi + + SpdDownloadLog=$(awk -v down=$SpdDownload -v mb=125000 'BEGIN{printf "%.0f\n", down/mb}') + SpdUploadLog=$(awk -v up=$SpdUpload -v mb=125000 'BEGIN{printf "%.0f\n", up/mb}') + SpdInterface=$WANIFNAME + + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - New Speedtest Results -- Down:$SpdDownloadLog Mbps | Up:$SpdUploadLog Mbps | Latency:$SpdLatency ms | Jitter:$SpdJitter ms | PacketLoss:$SpdPacketLoss %" >> $LOGFILE + + { echo 'SpdDate="'"$SpdDate"'"' + echo 'SpdServer="'"$SpdServer"'"' + echo 'SpdInterface="'"$SpdInterface"'"' + echo 'SpdLatency='$SpdLatency + echo 'SpdLatencyLo='$SpdLatencyLo + echo 'SpdLatencyHi='$SpdLatencyHi + echo 'SpdJitter='$SpdJitter + echo 'SpdPacketLoss='$SpdPacketLoss + echo 'SpdDownload='$SpdDownload + echo 'SpdUpload='$SpdUpload + echo 'SpdDLLatency='$SpdDLLatency + echo 'SpdDLLatencyJt='$SpdDLLatencyJt + echo 'SpdDLLatencyLo='$SpdDLLatencyLo + echo 'SpdDLLatencyHi='$SpdDLLatencyHi + echo 'SpdULLatency='$SpdULLatency + echo 'SpdULLatencyJt='$SpdULLatencyJt + echo 'SpdULLatencyLo='$SpdULLatencyLo + echo 'SpdULLatencyHi='$SpdULLatencyHi + } > "$SPDRESPATH" + printf "${CGreen}\r" + QueueSpdTest=0 + fi + + if [ "$1" = "1" ] || [ "$1" = "2" ] || [ "$1" = "3" ] || [ "$1" = "4" ] || [ "$1" = "5" ] + then + #run VPN speedtest and save Results + selectedvpnslot="vpn${1}on" + eval selectedvpnslot="\$${selectedvpnslot}" + if [ "$selectedvpnslot" = "True" ] && [ "$VPNSite2Site" = "0" ] + then + printf "\r${InvGreen} ${CClear} ${CGreen}[Initializing VPN$1 Speedtest]" + if [ $spdtestsvrID == "0" ]; then + speed="$(/jffs/addons/rtrmon.d/speedtest --format=csv --interface=tun1$1 --accept-license --accept-gdpr 2>&1)" + else + speed="$(/jffs/addons/rtrmon.d/speedtest --format=csv --interface=tun1$1 --server-id=$spdtestsvrID --accept-license --accept-gdpr 2>&1)" + fi + SpdDate=$(date) + SpdServer=$(echo $speed | awk -F '","' 'NR==1 {print $1}' | sed -e 's/^"//' -e 's/"$//' -e 's/[^a-zA-Z0-9 -]//g') + SpdLatency=$(echo $speed | awk -F '","' 'NR==1 {print $3}' | sed -e 's/^"//' -e 's/"$//') + SpdLatencyLo=$(echo $speed | awk -F '","' 'NR==1 {print $20}' | sed -e 's/^"//' -e 's/"$//') + SpdLatencyHi=$(echo $speed | awk -F '","' 'NR==1 {print $21}' | sed -e 's/^"//' -e 's/"$//') + SpdJitter=$(echo $speed | awk -F '","' 'NR==1 {print $4}' | sed -e 's/^"//' -e 's/"$//') + SpdPacketLoss=$(echo $speed | awk -F '","' 'NR==1 {print $5}' | sed -e 's/^"//' -e 's/"$//') + SpdDownload=$(echo $speed | awk -F '","' 'NR==1 {print $6}' | sed -e 's/^"//' -e 's/"$//') + SpdUpload=$(echo $speed | awk -F '","' 'NR==1 {print $7}' | sed -e 's/^"//' -e 's/"$//') + SpdDLLatency=$(echo $speed | awk -F '","' 'NR==1 {print $12}' | sed -e 's/^"//' -e 's/"$//') + SpdDLLatencyJt=$(echo $speed | awk -F '","' 'NR==1 {print $13}' | sed -e 's/^"//' -e 's/"$//') + SpdDLLatencyLo=$(echo $speed | awk -F '","' 'NR==1 {print $14}' | sed -e 's/^"//' -e 's/"$//') + SpdDLLatencyHi=$(echo $speed | awk -F '","' 'NR==1 {print $15}' | sed -e 's/^"//' -e 's/"$//') + SpdULLatency=$(echo $speed | awk -F '","' 'NR==1 {print $16}' | sed -e 's/^"//' -e 's/"$//') + SpdULLatencyJt=$(echo $speed | awk -F '","' 'NR==1 {print $17}' | sed -e 's/^"//' -e 's/"$//') + SpdULLatencyLo=$(echo $speed | awk -F '","' 'NR==1 {print $18}' | sed -e 's/^"//' -e 's/"$//') + SpdULLatencyHi=$(echo $speed | awk -F '","' 'NR==1 {print $19}' | sed -e 's/^"//' -e 's/"$//') + + if [ $SpdDownload -eq 0 ]; then SpdDownload=1; fi + if [ $SpdUpload -eq 0 ]; then SpdUpload=1; fi + + SpdDownloadLog=$(awk -v down=$SpdDownload -v mb=125000 'BEGIN{printf "%.0f\n", down/mb}') + SpdUploadLog=$(awk -v up=$SpdUpload -v mb=125000 'BEGIN{printf "%.0f\n", up/mb}') + SpdInterface="tun1$1" + + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - New VPN$1 Speedtest Results -- Down:$SpdDownloadLog Mbps | Up:$SpdUploadLog Mbps | Latency:$SpdLatency ms | Jitter:$SpdJitter ms | PacketLoss:$SpdPacketLoss %" >> $LOGFILE + + { echo 'SpdDate="'"$SpdDate"'"' + echo 'SpdServer="'"$SpdServer"'"' + echo 'SpdInterface="'"$SpdInterface"'"' + echo 'SpdLatency='$SpdLatency + echo 'SpdLatencyLo='$SpdLatencyLo + echo 'SpdLatencyHi='$SpdLatencyHi + echo 'SpdJitter='$SpdJitter + echo 'SpdPacketLoss='$SpdPacketLoss + echo 'SpdDownload='$SpdDownload + echo 'SpdUpload='$SpdUpload + echo 'SpdDLLatency='$SpdDLLatency + echo 'SpdDLLatencyJt='$SpdDLLatencyJt + echo 'SpdDLLatencyLo='$SpdDLLatencyLo + echo 'SpdDLLatencyHi='$SpdDLLatencyHi + echo 'SpdULLatency='$SpdULLatency + echo 'SpdULLatencyJt='$SpdULLatencyJt + echo 'SpdULLatencyLo='$SpdULLatencyLo + echo 'SpdULLatencyHi='$SpdULLatencyHi + } > $SPDRESPATH + printf "\r${CClear}" + QueueVPNSlot1=0 + QueueVPNSlot2=0 + QueueVPNSlot3=0 + QueueVPNSlot4=0 + QueueVPNSlot5=0 + else + printf "\r${InvRed} ${CClear}${CRed} [No valid VPN tunnel detected to run Speedtest on]${CClear}" + sleep 3 + printf "\r${CClear} " + QueueVPNSlot1=0 + QueueVPNSlot2=0 + QueueVPNSlot3=0 + QueueVPNSlot4=0 + QueueVPNSlot5=0 + fi + fi + + if [ "$1" = "0" ] || [ "$1" = "6" ] || [ "$1" = "7" ] || [ "$1" = "8" ] || [ "$1" = "9" ] + then + if [ $1 -eq 6 ]; then selectedslotnum=1 + elif [ $1 -eq 7 ]; then selectedslotnum=2 + elif [ $1 -eq 8 ]; then selectedslotnum=3 + elif [ $1 -eq 9 ]; then selectedslotnum=4 + elif [ $1 -eq 0 ]; then selectedslotnum=5 + fi + #run WG speedtest and save Results + selectedwgslot="wg${selectedslotnum}on" + eval selectedwgslot="\$${selectedwgslot}" + if [ "$selectedwgslot" = "True" ] && [ "$VPNSite2Site" = "0" ] + then + + SPDWGTUN="wgc$selectedslotnum" + SPDNVRAMWGSLOTADDR=$($timeoutcmd$timeoutsec nvram get "$SPDWGTUN"_addr | cut -d '/' -f1) + + # Added based on suggestion from @ZebMcKayhan + ip rule add from $SPDNVRAMWGSLOTADDR lookup $SPDWGTUN prio 10 >/dev/null 2>&1 + ip -6 rule add from all oif $SPDWGTUN lookup $SPDWGTUN prio 10 >/dev/null 2>&1 #Mod to handle IPv6 + + printf "\r${InvGreen} ${CClear} ${CGreen}[Initializing WG${selectedslotnum} Speedtest]" + + if [ $spdtestsvrID == "0" ]; then + speed="$(/jffs/addons/rtrmon.d/speedtest --format=csv --interface=wgc${selectedslotnum} --accept-license --accept-gdpr 2>&1)" + else + speed="$(/jffs/addons/rtrmon.d/speedtest --format=csv --interface=wgc${selectedslotnum} --server-id=$spdtestsvrID --accept-license --accept-gdpr 2>&1)" + fi + + # Added based on suggestion from @ZebMcKayhan + ip rule del prio 10 >/dev/null 2>&1 + ip -6 rule del prio 10 >/dev/null 2>&1 + + # Clean up any garbage data per @ZebMcKayhan + speed=$(echo $speed | sed 's/^[^"]*//') + + SpdDate=$(date) + SpdServer=$(echo $speed | awk -F '","' 'NR==1 {print $1}' | sed -e 's/^"//' -e 's/"$//' -e 's/[^a-zA-Z0-9 -]//g') + SpdLatency=$(echo $speed | awk -F '","' 'NR==1 {print $3}' | sed -e 's/^"//' -e 's/"$//') + SpdLatencyLo=$(echo $speed | awk -F '","' 'NR==1 {print $20}' | sed -e 's/^"//' -e 's/"$//') + SpdLatencyHi=$(echo $speed | awk -F '","' 'NR==1 {print $21}' | sed -e 's/^"//' -e 's/"$//') + SpdJitter=$(echo $speed | awk -F '","' 'NR==1 {print $4}' | sed -e 's/^"//' -e 's/"$//') + SpdPacketLoss=$(echo $speed | awk -F '","' 'NR==1 {print $5}' | sed -e 's/^"//' -e 's/"$//') + SpdDownload=$(echo $speed | awk -F '","' 'NR==1 {print $6}' | sed -e 's/^"//' -e 's/"$//') + SpdUpload=$(echo $speed | awk -F '","' 'NR==1 {print $7}' | sed -e 's/^"//' -e 's/"$//') + SpdDLLatency=$(echo $speed | awk -F '","' 'NR==1 {print $12}' | sed -e 's/^"//' -e 's/"$//') + SpdDLLatencyJt=$(echo $speed | awk -F '","' 'NR==1 {print $13}' | sed -e 's/^"//' -e 's/"$//') + SpdDLLatencyLo=$(echo $speed | awk -F '","' 'NR==1 {print $14}' | sed -e 's/^"//' -e 's/"$//') + SpdDLLatencyHi=$(echo $speed | awk -F '","' 'NR==1 {print $15}' | sed -e 's/^"//' -e 's/"$//') + SpdULLatency=$(echo $speed | awk -F '","' 'NR==1 {print $16}' | sed -e 's/^"//' -e 's/"$//') + SpdULLatencyJt=$(echo $speed | awk -F '","' 'NR==1 {print $17}' | sed -e 's/^"//' -e 's/"$//') + SpdULLatencyLo=$(echo $speed | awk -F '","' 'NR==1 {print $18}' | sed -e 's/^"//' -e 's/"$//') + SpdULLatencyHi=$(echo $speed | awk -F '","' 'NR==1 {print $19}' | sed -e 's/^"//' -e 's/"$//') + + if [ $SpdDownload -eq 0 ]; then SpdDownload=1; fi + if [ $SpdUpload -eq 0 ]; then SpdUpload=1; fi + + SpdDownloadLog=$(awk -v down=$SpdDownload -v mb=125000 'BEGIN{printf "%.0f\n", down/mb}') + SpdUploadLog=$(awk -v up=$SpdUpload -v mb=125000 'BEGIN{printf "%.0f\n", up/mb}') + SpdInterface="wgc${selectedslotnum}" + + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - New WG${selectedslotnum} Speedtest Results -- Down:$SpdDownloadLog Mbps | Up:$SpdUploadLog Mbps | Latency:$SpdLatency ms | Jitter:$SpdJitter ms | PacketLoss:$SpdPacketLoss %" >> $LOGFILE + + { echo 'SpdDate="'"$SpdDate"'"' + echo 'SpdServer="'"$SpdServer"'"' + echo 'SpdInterface="'"$SpdInterface"'"' + echo 'SpdLatency='$SpdLatency + echo 'SpdLatencyLo='$SpdLatencyLo + echo 'SpdLatencyHi='$SpdLatencyHi + echo 'SpdJitter='$SpdJitter + echo 'SpdPacketLoss='$SpdPacketLoss + echo 'SpdDownload='$SpdDownload + echo 'SpdUpload='$SpdUpload + echo 'SpdDLLatency='$SpdDLLatency + echo 'SpdDLLatencyJt='$SpdDLLatencyJt + echo 'SpdDLLatencyLo='$SpdDLLatencyLo + echo 'SpdDLLatencyHi='$SpdDLLatencyHi + echo 'SpdULLatency='$SpdULLatency + echo 'SpdULLatencyJt='$SpdULLatencyJt + echo 'SpdULLatencyLo='$SpdULLatencyLo + echo 'SpdULLatencyHi='$SpdULLatencyHi + } > $SPDRESPATH + printf "\r${CClear}" + QueueWGSlot1=0 + QueueWGSlot2=0 + QueueWGSlot3=0 + QueueWGSlot4=0 + QueueWGSlot5=0 + else + printf "\r${InvRed} ${CClear}${CRed} [No valid WG tunnel detected to run Speedtest on]${CClear}" + sleep 3 + printf "\r${CClear} " + QueueWGSlot1=0 + QueueWGSlot2=0 + QueueWGSlot3=0 + QueueWGSlot4=0 + QueueWGSlot5=0 + fi + fi + + # Display previous results + if [ $SpdDownload -eq 0 ] || [ -z $SpdDownload ]; then SpdDownload=1; fi + if [ $SpdUpload -eq 0 ] || [ -z $SpdUpload ]; then SpdUpload=1; fi + + SpdDownload=$(awk -v down=$SpdDownload -v mb=125000 'BEGIN{printf "%.0f\n", down/mb}') + SpdUpload=$(awk -v up=$SpdUpload -v mb=125000 'BEGIN{printf "%.0f\n", up/mb}') + + if [ "$ScreenshotMode" == "1" ]; then + SpdServer="Starlink Satellite Transceiver #488028" + fi + + if { [ "$vpn1on" = "True" ] || [ "$vpn2on" = "True" ] || [ "$vpn3on" = "True" ] || [ "$vpn4on" = "True" ] || [ "$vpn5on" = "True" ]; } && { [ "$wg1on" = "True" ] || [ "$wg2on" = "True" ] || [ "$wg3on" = "True" ] || [ "$wg4on" = "True" ] || [ "$wg5on" = "True" ]; }; then + printf "\r${InvGreen} ${CClear} ${CGreen}(I)${CWhite}nitiate WAN Speedtest on: ${CGreen}$WANIFNAME ${CWhite}| VPN 1:${CGreen}(1) ${CWhite}2:${CGreen}(2) ${CWhite}3:${CGreen}(3) ${CWhite}4:${CGreen}(4) ${CWhite}5:${CGreen}(5) ${CWhite} | WG 1:${CGreen}(6) ${CWhite}2:${CGreen}(7) ${CWhite}3:${CGreen}(8) ${CWhite}4:${CGreen}(9) ${CWhite}5:${CGreen}(0)${CClear}" + elif [ "$vpn1on" = "True" ] || [ "$vpn2on" = "True" ] || [ "$vpn3on" = "True" ] || [ "$vpn4on" = "True" ] || [ "$vpn5on" = "True" ]; then + printf "\r${InvGreen} ${CClear} ${CGreen}(I)${CWhite}nitiate WAN Speedtest on: ${CGreen}$WANIFNAME ${CWhite}| VPN 1:${CGreen}(1) ${CWhite}2:${CGreen}(2) ${CWhite}3:${CGreen}(3) ${CWhite}4:${CGreen}(4) ${CWhite}5:${CGreen}(5) ${CWhite} | ${CDkGray}WG 1:(6) 2:(7) 3:(8) 4:(9) 5:(0)${CClear}" + elif [ "$wg1on" = "True" ] || [ "$wg2on" = "True" ] || [ "$wg3on" = "True" ] || [ "$wg4on" = "True" ] || [ "$wg5on" = "True" ]; then + printf "\r${InvGreen} ${CClear} ${CGreen}(I)${CWhite}nitiate WAN Speedtest on: ${CGreen}$WANIFNAME ${CWhite}| ${CDkGray}VPN 1:(1) 2:(2) 3:(3) 4:(4) 5:(5) ${CWhite} | WG 1:${CGreen}(6) ${CWhite}2:${CGreen}(7) ${CWhite}3:${CGreen}(8) ${CWhite}4:${CGreen}(9) ${CWhite}5:${CGreen}(0)${CClear}" + else + printf "\r${InvGreen} ${CClear} ${CGreen}(I)${CWhite}nitiate WAN Speedtest${CClear} " + fi + + echo "" + echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${InvGreen} ${CClear} ${CWhite}Test Date ${CDkGray}[ ${CGreen}$SpdDate${CClear}" + echo -e "${InvGreen} ${CClear} ${CWhite}Server ${CDkGray}[ ${CGreen}$SpdServer${CClear}" + echo -e "${InvGreen} ${CClear} ${CWhite}Interface ${CDkGray}[ ${CGreen}$SpdInterface${CClear}" + echo "" + echo -e "${InvGreen} ${CClear} ${CWhite}Idle Latency ${CDkGray}[ ${CGreen}$SpdLatency (ms)${CWhite} | Latency Low: ${CGreen}$SpdLatencyLo (ms) ${CWhite}| High: ${CGreen}$SpdLatencyHi (ms)${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} ${CWhite}Idle Jitter ${CDkGray}[ ${CGreen}$SpdJitter (ms)${CClear}" + echo -e "${InvGreen} ${CClear} ${CWhite}PacketLoss ${CDkGray}[ ${CGreen}$SpdPacketLoss (%)${CClear}" + echo "" + echo -e "${InvGreen} ${CClear} ${CWhite}Download ${CDkGray}[ ${CGreen}$SpdDownload (Mbps)${CWhite} | Jitter: ${CGreen}$SpdDLLatencyJt (ms)${CClear}" + echo -e "${InvGreen} ${CClear} ${CDkGray} [ ${CWhite}Latency: ${CGreen}$SpdDLLatency (ms)${CWhite} | Latency Low: ${CGreen}$SpdDLLatencyLo (ms) ${CWhite}| High: ${CGreen}$SpdDLLatencyHi (ms)${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} ${CCyan}Upload ${CDkGray}[ ${CGreen}$SpdUpload (Mbps)${CWhite} | Jitter: ${CGreen}$SpdULLatencyJt (ms)${CClear}" + echo -e "${InvGreen} ${CClear} ${CDkGray} [ ${CWhite}Latency: ${CGreen}$SpdULLatency (ms)${CWhite} | Latency Low: ${CGreen}$SpdULLatencyLo (ms) ${CWhite}| High: ${CGreen}$SpdULLatencyHi (ms)${CClear}" + echo "" + preparebar 79 "|" + progressbar $SpdDownload $MaxSpeedInet " DL vs WAN " "Mbps" "Reverse" $SpdDownload $MaxSpeedInet + echo "" + preparebar 79 "|" + progressbar $SpdUpload $MaxSpeedInetUL " UL vs WAN " "Mbps" "Reverse" $SpdUpload $MaxSpeedInetUL +} + +# ------------------------------------------------------------------------------------------------------------------------- + +# This function displays the stats UI for page 5 which includes network diagnostics and open port scanning +DisplayPage5() +{ + local ALIVE + local YEAR + local NW_STATE + local RES_STATE + local HOST_STATE + local CURL_STATE + local SPIDER_STATE + local SSL_STATE + #oldwan0ip="123.45.67.89" + + # Check to see if previous results are available to display + if [ -f "$DIAGRESPATH" ]; then + source "$DIAGRESPATH" + else + Lastruntime="No previous results found" + LocalClockTest="Failed" + NetworkConnTest="Failed" + NetworkResTest="Failed" + DigFuncTest="Failed" + CurlFuncTest="Failed" + SpiderFuncTest="Failed" + SSLHandshakeTest="Failed" + fi + + clear + if [ "$UpdateNotify" != "0" ]; then + echo -e "$UpdateNotify${CClear}" + fi + showheader + echo "" + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} Network Diagnostics ${CClear}" + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear} ${CWhite}Run ${CGreen}(D)${CWhite}iagnostics | Last Run Date/Time: ${CGreen}$Lastruntime" + echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo "" + + if [ "$QueueNetworkDiag" = "1" ] + then + #run network diags and save Results + printf "${InvYellow} ${CClear} ${CWhite}Local Clock Test... ${CYellow}[Checking] ${CDkGray}| date > 1970${CClear}" + YEAR="$(/bin/date +"%Y")" + sleep 1 + if [ "$YEAR" -gt 1970 ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Local Clock Test... ${CGreen}[Passed] ${CDkGray}| date > 1970${CClear}" + LocalClockTest="Passed" + else + printf "\r${InvRed} ${CClear} ${CWhite}Local Clock Test... ${CRed}[Failed] ${CDkGray}| date > 1970${CClear}" + LocalClockTest="Failed" + fi + echo "" + printf "${InvYellow} ${CClear} ${CWhite}Network Connectivity Test... ${CYellow}[Checking] ${CDkGray}| ping 1.1.1.1 -c1 -W2${CClear}" + NW_STATE="$(ping 1.1.1.1 -c1 -W2 >/dev/null 2>&1; echo $?)" + sleep 1 + if [ "$NW_STATE" = "0" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Network Connectivity Test... ${CGreen}[Passed] ${CDkGray}| ping 1.1.1.1 -c1 -W2${CClear}" + NetworkConnTest="Passed" + else + printf "\r${InvRed} ${CClear} ${CWhite}Network Connectivity Test... ${CRed}[Failed] ${CDkGray}| ping 1.1.1.1 -c1 -W2${CClear}" + NetworkConnTest="Failed" + fi + echo "" + + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + printf "${InvYellow} ${CClear} ${CWhite}Network Resolution Test... ${CYellow}[Checking] ${CDkGray}| nslookup google.com 127.0.0.1${CClear}" + RES_STATE="$(nslookup google.com 127.0.0.1 >/dev/null 2>&1; echo $?)" + sleep 1 + if [ "$RES_STATE" = "0" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Network Resolution Test... ${CGreen}[Passed] ${CDkGray}| nslookup google.com 127.0.0.1${CClear}" + NetworkResTest="Passed" + else + printf "\r${InvRed} ${CClear} ${CWhite}Network Resolution Test... ${CRed}[Failed] ${CDkGray}| nslookup google.com 127.0.0.1${CClear}" + NetworkResTest="Failed" + fi + echo "" + else + printf "${InvYellow} ${CClear} ${CWhite}Network Resolution Test... ${CYellow}[Checking] ${CDkGray}| nslookup google.com${CClear}" + RES_STATE="$(nslookup google.com >/dev/null 2>&1; echo $?)" + sleep 1 + if [ "$RES_STATE" = "0" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Network Resolution Test... ${CGreen}[Passed] ${CDkGray}| nslookup google.com${CClear}" + NetworkResTest="Passed" + else + printf "\r${InvRed} ${CClear} ${CWhite}Network Resolution Test... ${CRed}[Failed] ${CDkGray}| nslookup google.com${CClear}" + NetworkResTest="Failed" + fi + echo "" + fi + + printf "${InvYellow} ${CClear} ${CWhite}Dig Functionality Test... ${CYellow}[Checking] ${CDkGray}| dig google.com${CClear}" + DIG_STATE="$(dig google.com >/dev/null 2>&1; echo $?)" + sleep 1 + if [ "$DIG_STATE" = "0" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Dig Functionality Test... ${CGreen}[Passed] ${CDkGray}| dig google.com${CClear}" + DigFuncTest="Passed" + else + printf "\r${InvRed} ${CClear} ${CWhite}Dig Functionality Test... ${CRed}[Failed] ${CDkGray}| dig google.com${CClear}" + DigFuncTest="Failed" + fi + echo "" + + printf "${InvYellow} ${CClear} ${CWhite}Curl Functionality Test... ${CYellow}[Checking] ${CDkGray}| curl -Is http://www.google.com | head -n 1${CClear}" + CURL_STATE="$(curl -Is http://www.google.com | head -n 1 >/dev/null 2>&1; echo $?)" + sleep 1 + if [ "$CURL_STATE" = "0" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Curl Functionality Test... ${CGreen}[Passed] ${CDkGray}| curl -Is http://www.google.com | head -n 1${CClear}" + CurlFuncTest="Passed" + else + printf "\r${InvRed} ${CClear} ${CWhite}Curl Functionality Test... ${CRed}[Failed] ${CDkGray}| curl -Is http://www.google.com | head -n 1${CClear}" + CurlFuncTest="Failed" + fi + echo "" + + printf "${InvYellow} ${CClear} ${CWhite}Spider Functionality Test... ${CYellow}[Checking] ${CDkGray}| wget -q --spider http://google.com${CClear}" + SPIDER_STATE="$(wget -q --spider http://google.com >/dev/null 2>&1; echo $?)" + sleep 1 + if [ "$SPIDER_STATE" = "0" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Spider Functionality Test... ${CGreen}[Passed] ${CDkGray}| wget -q --spider http://google.com${CClear}" + SpiderFuncTest="Passed" + else + printf "\r${InvRed} ${CClear} ${CWhite}Spider Functionality Test... ${CRed}[Failed] ${CDkGray}| wget -q --spider http://google.com${CClear}" + SpiderFuncTest="Failed" + fi + echo "" + + printf "${InvYellow} ${CClear} ${CWhite}SSL Handshake Test... ${CYellow}[Checking] ${CDkGray}| nc -w3 8.8.8.8 443 && echo | openssl s_client -connect 8.8.8.8:443>${CClear}" + SSL_STATE="$(nc -w3 8.8.8.8 443 >/dev/null 2>&1 && echo | openssl s_client -connect 8.8.8.8:443 >/dev/null 2>&1 | awk 'handshake && $1 == "Verification" { if ($2=="OK") exit; exit 1 } $1 $2 == "SSLhandshake" { handshake = 1 }' >/dev/null 2>&1; echo $?)" + sleep 1 + if [ "$SSL_STATE" = "0" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}SSL Handshake Test... ${CGreen}[Passed] ${CDkGray}| nc -w3 8.8.8.8 443 && echo | openssl s_client -connect 8.8.8.8:443>${CClear}" + SSLHandshakeTest="Passed" + else + printf "\r${InvRed} ${CClear} ${CWhite}SSL Handshake Test... ${CRed}[Failed] ${CDkGray}| nc -w3 8.8.8.8 443 && echo | openssl s_client -connect 8.8.8.8:443>${CClear}" + SSLHandshakeTest="Failed" + fi + echo "" + echo "" + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} NMAP Port Scan Results ${CClear}" + + if [ "$PSView" == "TCP" ]; then + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} Show Open ${InvDkGray} ${CGreen}(T)${CWhite}CP ${CClear}${CWhite} Ports | Show Open ${CGreen}(U)${CWhite}DP Ports${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo "" + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + echo -e "${InvGreen} ${CClear} ${CWhite}WAN0 IP: ${CGreen}$oldwan0ip${CClear}" + WANnmap=$(nmap $oldwan0ip | grep "open") + if [ -z "$WANnmap" ]; then echo "None"; else nmap $oldwan0ip | grep "open"; fi + echo "" + fi + echo -e "${InvGreen} ${CClear} ${CWhite}BR0 IP: ${CGreen}$oldlanip${CClear}" + LANnmap=$(nmap $oldlanip | grep "open") + if [ -z "$LANnmap" ]; then echo "None"; else nmap $oldlanip | grep "open"; fi + elif [ "$PSView" == "UDP" ]; then + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} Show Open ${CGreen}(T)${CWhite}CP Ports | Show Open ${InvDkGray} ${CGreen}(U)${CWhite}DP ${CClear}${CWhite} Ports${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo "" + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + echo -e "${InvGreen} ${CClear} ${CWhite}WAN0 IP: ${CGreen}$oldwan0ip${CClear}" + WANUnmap=$(nmap -sU $oldwan0ip | grep "open") + if [ -z "$WANUnmap" ]; then echo "None"; else nmap -sU $oldwan0ip | grep "open"; fi + echo "" + fi + echo -e "${InvGreen} ${CClear} ${CWhite}BR0 IP: ${CGreen}$oldlanip${CClear}" + LANUnmap=$(nmap -sU $oldlanip | grep "open") + if [ -z "$LANUnmap" ]; then echo "None"; else nmap -sU $oldlanip | grep "open"; fi + fi + + { echo 'Lastruntime="'"$(date)"'"' + echo 'LocalClockTest="'"$LocalClockTest"'"' + echo 'NetworkConnTest="'"$NetworkConnTest"'"' + echo 'NetworkResTest="'"$NetworkResTest"'"' + echo 'DigFuncTest="'"$DigFuncTest"'"' + echo 'CurlFuncTest="'"$CurlFuncTest"'"' + echo 'SpiderFuncTest="'"$SpiderFuncTest"'"' + echo 'SSLHandshakeTest="'"$SSLHandshakeTest"'"' + } > $DIAGRESPATH + + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + nmap $oldwan0ip -oN $NMAPWANRESPATH | grep "open" >/dev/null 2>&1 + nmap $oldwan0ip -sU -oN $NMAPUWANRESPATH | grep "open" >/dev/null 2>&1 + fi + + nmap $oldlanip -oN $NMAPLANRESPATH | grep "open" >/dev/null 2>&1 + nmap $oldlanip -sU -oN $NMAPULANRESPATH | grep "open" >/dev/null 2>&1 + + QueueNetworkDiag=0 + +else + + if [ "$LocalClockTest" == "Passed" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Local Clock Test... ${CGreen}[Passed] ${CDkGray}| date > 1970${CClear}" + else + printf "\r${InvRed} ${CClear} ${CWhite}Local Clock Test... ${CRed}[Failed] ${CDkGray}| date > 1970${CClear}" + fi + echo "" + if [ "$NetworkConnTest" == "Passed" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Network Connectivity Test... ${CGreen}[Passed] ${CDkGray}| ping 1.1.1.1 -c1 -W2${CClear}" + else + printf "\r${InvRed} ${CClear} ${CWhite}Network Connectivity Test... ${CRed}[Failed] ${CDkGray}| ping 1.1.1.1 -c1 -W2${CClear}" + fi + echo "" + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + if [ "$NetworkResTest" == "Passed" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Network Resolution Test... ${CGreen}[Passed] ${CDkGray}| nslookup google.com 127.0.0.1${CClear}" + else + printf "\r${InvRed} ${CClear} ${CWhite}Network Resolution Test... ${CRed}[Failed] ${CDkGray}| nslookup google.com 127.0.0.1${CClear}" + fi + else + if [ "$NetworkResTest" == "Passed" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Network Resolution Test... ${CGreen}[Passed] ${CDkGray}| nslookup google.com${CClear}" + else + printf "\r${InvRed} ${CClear} ${CWhite}Network Resolution Test... ${CRed}[Failed] ${CDkGray}| nslookup google.com${CClear}" + fi + fi + echo "" + if [ "$DigFuncTest" == "Passed" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Dig Functionality Test... ${CGreen}[Passed] ${CDkGray}| dig google.com${CClear}" + else + printf "\r${InvRed} ${CClear} ${CWhite}Dig Functionality Test... ${CRed}[Failed] ${CDkGray}| dig google.com${CClear}" + fi + echo "" + if [ "$CurlFuncTest" == "Passed" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Curl Functionality Test... ${CGreen}[Passed] ${CDkGray}| curl -Is http://www.google.com | head -n 1${CClear}" + else + printf "\r${InvRed} ${CClear} ${CWhite}Curl Functionality Test... ${CRed}[Failed] ${CDkGray}| curl -Is http://www.google.com | head -n 1${CClear}" + fi + echo "" + if [ "$SpiderFuncTest" == "Passed" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}Spider Functionality Test... ${CGreen}[Passed] ${CDkGray}| wget -q --spider http://google.com${CClear}" + else + printf "\r${InvRed} ${CClear} ${CWhite}Spider Functionality Test... ${CRed}[Failed] ${CDkGray}| wget -q --spider http://google.com${CClear}" + fi + echo "" + if [ "$SSLHandshakeTest" == "Passed" ]; then + printf "\r${InvGreen} ${CClear} ${CWhite}SSL Handshake Test... ${CGreen}[Passed] ${CDkGray}| nc -w3 8.8.8.8 443 && echo | openssl s_client -connect 8.8.8.8:443>${CClear}" + else + printf "\r${InvRed} ${CClear} ${CWhite}SSL Handshake Test... ${CRed}[Failed] ${CDkGray}| nc -w3 8.8.8.8 443 && echo | openssl s_client -connect 8.8.8.8:443>${CClear}" + fi + echo "" + echo "" + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} NMAP Port Scan Results ${CClear}" + + if [ "$PSView" == "TCP" ]; then + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} Show Open ${InvDkGray} ${CGreen}(T)${CWhite}CP ${CClear}${CWhite} Ports | Show Open ${CGreen}(U)${CWhite}DP Ports${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo "" + if [ "$ScreenshotMode" == "1" ]; then + oldwan0ip="12.34.56.78" #demo + fi + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + echo -e "${InvGreen} ${CClear} ${CWhite}WAN0 IP: ${CGreen}$oldwan0ip${CClear}" + if [ ! -f $NMAPWANRESPATH ]; then + echo "None" + else + WANnmap=$(cat $NMAPWANRESPATH | grep "open") + if [ -z "$WANnmap" ]; then echo "None"; else cat $NMAPWANRESPATH | grep "open"; fi + fi + echo "" + fi + echo -e "${InvGreen} ${CClear} ${CWhite}BR0 IP: ${CGreen}$oldlanip${CClear}" + if [ ! -f $NMAPLANRESPATH ]; then + echo "None" + else + LANnmap=$(cat $NMAPLANRESPATH | grep "open") + if [ -z "$LANnmap" ]; then echo "None"; else cat $NMAPLANRESPATH | grep "open"; fi + fi + elif [ "$PSView" == "UDP" ]; then + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} Show Open ${CGreen}(T)${CWhite}CP Ports | Show Open ${InvDkGray} ${CGreen}(U)${CWhite}DP ${CClear}${CWhite} Ports${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo "" + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + echo -e "${InvGreen} ${CClear} ${CWhite}WAN0 IP: ${CGreen}$oldwan0ip${CClear}" + if [ ! -f $NMAPUWANRESPATH ]; then + echo "None" + else + WANUnmap=$(cat $NMAPUWANRESPATH | grep "open") + if [ -z "$WANUnmap" ]; then echo "None"; else cat $NMAPUWANRESPATH | grep "open"; fi + fi + echo "" + fi + echo -e "${InvGreen} ${CClear} ${CWhite}BR0 IP: ${CGreen}$oldlanip${CClear}" + if [ ! -f $NMAPULANRESPATH ]; then + echo "None" + else + LANUnmap=$(cat $NMAPULANRESPATH | grep "open") + if [ -z "$LANUnmap" ]; then echo "None"; else cat $NMAPULANRESPATH | grep "open"; fi + fi + fi +fi +} + +# ------------------------------------------------------------------------------------------------------------------------- + +# This function displays the stats UI for page 6 which includes top bandwidth connections for WAN, LAN and VPN +DisplayPage6() +{ + clear + if [ "$UpdateNotify" != "0" ]; then + echo -e "$UpdateNotify${CClear}" + fi + showheader + echo "" + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} Top 10 Network Connections/Bandwidth Stats ${CClear}" + echo -e "${InvGreen} ${CClear}" + + if [ "$QueueNetworkConn" = "1" ] + then + #run network diags and save Results + printf "${InvGreen} ${CClear} ${CWhite}[Updating WAN( ) LAN( ) VPN( ) WG( ) Statistics ... Please stand by...]" + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + timeout 15 iftop -t -s 10 -i $WANIFNAME 2>&1 | sed '/^==/ q' > /jffs/addons/rtrmon.d/wanresult.txt + fi + printf "\r${InvGreen} ${CClear} ${CWhite}[Updating WAN(${CGreen}X${CWhite}) LAN( ) VPN( ) WG( ) Statistics ... Please stand by...]" + timeout 15 iftop -t -s 10 -i br0 2>&1 | sed '/^==/ q' > /jffs/addons/rtrmon.d/lanresult.txt + printf "\r${InvGreen} ${CClear} ${CWhite}[Updating WAN(${CGreen}X${CWhite}) LAN(${CGreen}X${CWhite}) VPN( ) WG( ) Statistics ... Please stand by...]" + + if [ "$vpn1on" == "True" ] || [ "$vpn2on" == "True" ] || [ "$vpn3on" == "True" ] || [ "$vpn4on" == "True" ] || [ "$vpn5on" == "True" ] + then + slot=0 + while [ "$slot" -ne 5 ] + do + slot="$((slot+1))" + selectedslot="vpn${slot}on" + eval selectedslot="\$${selectedslot}" + if [ "$selectedslot" = "True" ] && [ "$VPNSite2Site" = "0" ] + then + NVRAMVPNSLOTADDR=$($timeoutcmd$timeoutsec nvram get vpn_client"$slot"_addr) + NVRAMVPNSLOTIP=$(ping -c 1 -w 1 $NVRAMVPNSLOTADDR | awk -F '[()]' '/PING/ { print $2}') + if [ "$(echo "$NVRAMVPNSLOTIP" | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then + { echo 'Private Tunnel' + } > /jffs/addons/rtrmon.d/vpn${slot}result.txt + else + timeout 15 iftop -t -s 10 -i tun1$slot 2>&1 | sed '/^==/ q' > /jffs/addons/rtrmon.d/vpn${slot}result.txt + fi + fi + done + fi + + printf "\r${InvGreen} ${CClear} ${CWhite}[Updating WAN(${CGreen}X${CWhite}) LAN(${CGreen}X${CWhite}) VPN(${CGreen}X${CWhite}) WG( ) Statistics ... Please stand by...]" + + if [ "$wg1on" == "True" ] || [ "$wg2on" == "True" ] || [ "$wg3on" == "True" ] || [ "$wg4on" == "True" ] || [ "$wg5on" == "True" ] + then + slot=0 + while [ "$slot" -ne 5 ] + do + slot="$((slot+1))" + selectedslot="wg${slot}on" + eval selectedslot="\$${selectedslot}" + if [ "$selectedslot" = "True" ] && [ "$VPNSite2Site" = "0" ] + then + WGTUN="wgc$slot" + NVRAMWGSLOTADDR=$($timeoutcmd$timeoutsec nvram get "$WGTUN"_addr | cut -d '/' -f1) + + # Added based on suggestion from @ZebMcKayhan + ip rule add from $NVRAMWGSLOTADDR lookup $WGTUN prio 10 >/dev/null 2>&1 + + icanhazwgip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN" --request GET --url https://ipv4.icanhazip.com" + icanhazwgip="$(eval $icanhazwgip)" + if [ -z "$icanhazwgip" ] || echo "$icanhazwgip" | grep -qoE 'Internet|traffic|Error|error' + then + { echo 'Error determining WG$slot IP' + } > /jffs/addons/rtrmon.d/wgc${slot}result.txt + else + NVRAMWGIP="$icanhazwgip" + fi + + # Added based on suggestion from @ZebMcKayhan + ip rule del prio 10 >/dev/null 2>&1 + + if [ "$(echo "$NVRAMWGIP" | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then + { echo 'Private Tunnel' + } > /jffs/addons/rtrmon.d/wgc${slot}result.txt + else + timeout 15 iftop -t -s 10 -i wgc$slot 2>&1 | sed '/^==/ q' > /jffs/addons/rtrmon.d/wgc${slot}result.txt + fi + fi + done + fi + + printf "\r${InvGreen} ${CClear} ${CWhite}[Updating WAN(${CGreen}X${CWhite}) LAN(${CGreen}X${CWhite}) VPN(${CGreen}X${CWhite}) WG(${CGreen}X${CWhite}) Statistics ... Please stand by...]" + sleep 1 + printf "\r " + QueueNetworkConn=0 + testrun="$(date +%s)" + + if [ -z "${testrun:+xSETx}" ] + then + lastrun="Not Current" + else + currtime="$(date +%s)" + mindiffs="$(( ($currtime - $testrun)/60 ))" + lastrun="$mindiffs Minute(s) ago" + fi + + echo -e "\r${InvGreen} ${CClear} ${CWhite}Refresh ${CGreen}(C)${CWhite}urrent Statistics | Stats Age: ${CGreen}$lastrun${CClear}" + else + if [ -z "${testrun:+xSETx}" ] + then + lastrun="Not Current" + else + currtime="$(date +%s)" + mindiffs="$(( ($currtime - $testrun)/60 ))" + lastrun="$mindiffs Minute(s) ago" + fi + echo -e "${InvGreen} ${CClear} ${CWhite}Refresh ${CGreen}(C)${CWhite}urrent Statistics | Stats Age: ${CGreen}$lastrun${CClear}" + fi + + if [ "$NCView" == "WAN" ]; then + if [ "$vpn1on" == "True" ] || [ "$vpn2on" == "True" ] || [ "$vpn3on" == "True" ] || [ "$vpn4on" == "True" ] || [ "$vpn5on" == "True" ] || [ "$wg1on" == "True" ] || [ "$wg2on" == "True" ] || [ "$wg3on" == "True" ] || [ "$wg4on" == "True" ] || [ "$wg5on" == "True" ]; then + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} View ${InvDkGray} ${CGreen}(W)${CWhite}AN ${CClear}${CWhite} | ${CGreen}(L)${CWhite}AN | ${CGreen}(V)${CWhite}PN | W${CGreen}(G)${CClear}" + else + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} View ${InvDkGray} ${CGreen}(W)${CWhite}AN ${CClear}${CWhite} | ${CGreen}(L)${CWhite}AN${CClear}" + fi + + echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo "" + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} WAN ${CClear}" + + wansegments1=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==7 {print $1, $2, $4} NR==8 {print $1, $3}') + + line1="$(echo $wansegments1 | awk '{print $1}')" + dest1="$(echo $wansegments1 | awk '{print $2}')" + out1="$(echo $wansegments1 | awk '{print $3}')" + src1="$(echo $wansegments1 | awk '{print $4}')" + in1="$(echo $wansegments1 | awk '{print $5}')" + + wansegments2=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==9 {print $1, $2, $4} NR==10 {print $1, $3}') + + line2="$(echo $wansegments2 | awk '{print $1}')" + dest2="$(echo $wansegments2 | awk '{print $2}')" + out2="$(echo $wansegments2 | awk '{print $3}')" + src2="$(echo $wansegments2 | awk '{print $4}')" + in2="$(echo $wansegments2 | awk '{print $5}')" + + wansegments3=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==11 {print $1, $2, $4} NR==12 {print $1, $3}') + + line3="$(echo $wansegments3 | awk '{print $1}')" + dest3="$(echo $wansegments3 | awk '{print $2}')" + out3="$(echo $wansegments3 | awk '{print $3}')" + src3="$(echo $wansegments3 | awk '{print $4}')" + in3="$(echo $wansegments3 | awk '{print $5}')" + + wansegments4=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==13 {print $1, $2, $4} NR==14 {print $1, $3}') + + line4="$(echo $wansegments4 | awk '{print $1}')" + dest4="$(echo $wansegments4 | awk '{print $2}')" + out4="$(echo $wansegments4 | awk '{print $3}')" + src4="$(echo $wansegments4 | awk '{print $4}')" + in4="$(echo $wansegments4 | awk '{print $5}')" + + wansegments5=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==15 {print $1, $2, $4} NR==16 {print $1, $3}') + + line5="$(echo $wansegments5 | awk '{print $1}')" + dest5="$(echo $wansegments5 | awk '{print $2}')" + out5="$(echo $wansegments5 | awk '{print $3}')" + src5="$(echo $wansegments5 | awk '{print $4}')" + in5="$(echo $wansegments5 | awk '{print $5}')" + + wansegments6=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==17 {print $1, $2, $4} NR==18 {print $1, $3}') + + line6="$(echo $wansegments6 | awk '{print $1}')" + dest6="$(echo $wansegments6 | awk '{print $2}')" + out6="$(echo $wansegments6 | awk '{print $3}')" + src6="$(echo $wansegments6 | awk '{print $4}')" + in6="$(echo $wansegments6 | awk '{print $5}')" + + wansegments7=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==19 {print $1, $2, $4} NR==20 {print $1, $3}') + + line7="$(echo $wansegments7 | awk '{print $1}')" + dest7="$(echo $wansegments7 | awk '{print $2}')" + out7="$(echo $wansegments7 | awk '{print $3}')" + src7="$(echo $wansegments7 | awk '{print $4}')" + in7="$(echo $wansegments7 | awk '{print $5}')" + + wansegments8=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==21 {print $1, $2, $4} NR==22 {print $1, $3}') + + line8="$(echo $wansegments8 | awk '{print $1}')" + dest8="$(echo $wansegments8 | awk '{print $2}')" + out8="$(echo $wansegments8 | awk '{print $3}')" + src8="$(echo $wansegments8 | awk '{print $4}')" + in8="$(echo $wansegments8 | awk '{print $5}')" + + wansegments9=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==23 {print $1, $2, $4} NR==24 {print $1, $3}') + + line9="$(echo $wansegments9 | awk '{print $1}')" + dest9="$(echo $wansegments9 | awk '{print $2}')" + out9="$(echo $wansegments9 | awk '{print $3}')" + src9="$(echo $wansegments9 | awk '{print $4}')" + in9="$(echo $wansegments9 | awk '{print $5}')" + + wansegments10=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==25 {print $1, $2, $4} NR==26 {print $1, $3}') + + line10="$(echo $wansegments10 | awk '{print $1}')" + dest10="$(echo $wansegments10 | awk '{print $2}')" + out10="$(echo $wansegments10 | awk '{print $3}')" + src10="$(echo $wansegments10 | awk '{print $4}')" + in10="$(echo $wansegments10 | awk '{print $5}')" + + if [ "$line1" == "1" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line1 $dest1 <=> $src1" " Out: $out1 | In: $in1" + else + echo "No Data" + fi + + if [ "$line2" == "2" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line2 $dest2 <=> $src2" " Out: $out2 | In: $in2" + fi + + if [ "$line3" == "3" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line3 $dest3 <=> $src3" " Out: $out3 | In: $in3" + fi + + if [ "$line4" == "4" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line4 $dest4 <=> $src4" " Out: $out4 | In: $in4" + fi + + if [ "$line5" == "5" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line5 $dest5 <=> $src5" " Out: $out5 | In: $in5" + fi + + if [ "$line6" == "6" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line6 $dest6 <=> $src6" " Out: $out6 | In: $in6" + fi + + if [ "$line7" == "7" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line7 $dest7 <=> $src7" " Out: $out7 | In: $in7" + fi + + if [ "$line8" == "8" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line8 $dest8 <=> $src8" " Out: $out8 | In: $in8" + fi + + if [ "$line9" == "9" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line9 $dest9 <=> $src9" " Out: $out9 | In: $in9" + fi + + if [ "$line10" == "10" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" "$line10 $dest10 <=> $src10" " Out: $out10 | In: $in10" + fi + fi + + if [ "$NCView" == "LAN" ]; then + if [ "$vpn1on" == "True" ] || [ "$vpn2on" == "True" ] || [ "$vpn3on" == "True" ] || [ "$vpn4on" == "True" ] || [ "$vpn5on" == "True" ] || [ "$wg1on" == "True" ] || [ "$wg2on" == "True" ] || [ "$wg3on" == "True" ] || [ "$wg4on" == "True" ] || [ "$wg5on" == "True" ]; then + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} View ${CGreen}(W)${CWhite}AN | ${InvDkGray} ${CGreen}(L)${CWhite}AN ${CClear}${CWhite} | ${CGreen}(V)${CWhite}PN | W${CGreen}(G)${CClear}" + else + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} View ${CGreen}(W)${CWhite}AN | ${InvDkGray} ${CGreen}(L)${CWhite}AN ${CClear}" + fi + + echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo "" + + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} LAN ${CClear}" + + lansegments1=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==7 {print $1, $2, $4} NR==8 {print $1, $3}') + + line1="$(echo $lansegments1 | awk '{print $1}')" + dest1="$(echo $lansegments1 | awk '{print $2}')" + out1="$(echo $lansegments1 | awk '{print $3}')" + src1="$(echo $lansegments1 | awk '{print $4}')" + in1="$(echo $lansegments1 | awk '{print $5}')" + + lansegments2=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==9 {print $1, $2, $4} NR==10 {print $1, $3}') + + line2="$(echo $lansegments2 | awk '{print $1}')" + dest2="$(echo $lansegments2 | awk '{print $2}')" + out2="$(echo $lansegments2 | awk '{print $3}')" + src2="$(echo $lansegments2 | awk '{print $4}')" + in2="$(echo $lansegments2 | awk '{print $5}')" + + lansegments3=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==11 {print $1, $2, $4} NR==12 {print $1, $3}') + + line3="$(echo $lansegments3 | awk '{print $1}')" + dest3="$(echo $lansegments3 | awk '{print $2}')" + out3="$(echo $lansegments3 | awk '{print $3}')" + src3="$(echo $lansegments3 | awk '{print $4}')" + in3="$(echo $lansegments3 | awk '{print $5}')" + + lansegments4=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==13 {print $1, $2, $4} NR==14 {print $1, $3}') + + line4="$(echo $lansegments4 | awk '{print $1}')" + dest4="$(echo $lansegments4 | awk '{print $2}')" + out4="$(echo $lansegments4 | awk '{print $3}')" + src4="$(echo $lansegments4 | awk '{print $4}')" + in4="$(echo $lansegments4 | awk '{print $5}')" + + lansegments5=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==15 {print $1, $2, $4} NR==16 {print $1, $3}') + + line5="$(echo $lansegments5 | awk '{print $1}')" + dest5="$(echo $lansegments5 | awk '{print $2}')" + out5="$(echo $lansegments5 | awk '{print $3}')" + src5="$(echo $lansegments5 | awk '{print $4}')" + in5="$(echo $lansegments5 | awk '{print $5}')" + + lansegments6=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==17 {print $1, $2, $4} NR==18 {print $1, $3}') + + line6="$(echo $lansegments6 | awk '{print $1}')" + dest6="$(echo $lansegments6 | awk '{print $2}')" + out6="$(echo $lansegments6 | awk '{print $3}')" + src6="$(echo $lansegments6 | awk '{print $4}')" + in6="$(echo $lansegments6 | awk '{print $5}')" + + lansegments7=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==19 {print $1, $2, $4} NR==20 {print $1, $3}') + + line7="$(echo $lansegments7 | awk '{print $1}')" + dest7="$(echo $lansegments7 | awk '{print $2}')" + out7="$(echo $lansegments7 | awk '{print $3}')" + src7="$(echo $lansegments7 | awk '{print $4}')" + in7="$(echo $lansegments7 | awk '{print $5}')" + + lansegments8=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==21 {print $1, $2, $4} NR==22 {print $1, $3}') + + line8="$(echo $lansegments8 | awk '{print $1}')" + dest8="$(echo $lansegments8 | awk '{print $2}')" + out8="$(echo $lansegments8 | awk '{print $3}')" + src8="$(echo $lansegments8 | awk '{print $4}')" + in8="$(echo $lansegments8 | awk '{print $5}')" + + lansegments9=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==23 {print $1, $2, $4} NR==24 {print $1, $3}') + + line9="$(echo $lansegments9 | awk '{print $1}')" + dest9="$(echo $lansegments9 | awk '{print $2}')" + out9="$(echo $lansegments9 | awk '{print $3}')" + src9="$(echo $lansegments9 | awk '{print $4}')" + in9="$(echo $lansegments9 | awk '{print $5}')" + + lansegments10=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==25 {print $1, $2, $4} NR==26 {print $1, $3}') + + line10="$(echo $lansegments10 | awk '{print $1}')" + dest10="$(echo $lansegments10 | awk '{print $2}')" + out10="$(echo $lansegments10 | awk '{print $3}')" + src10="$(echo $lansegments10 | awk '{print $4}')" + in10="$(echo $lansegments10 | awk '{print $5}')" + + if [ "$line1" == "1" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line1 $dest1 <=> $src1" " Out: $out1 | In: $in1" + else + echo "No Data" + fi + + if [ "$line2" == "2" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line2 $dest2 <=> $src2" " Out: $out2 | In: $in2" + fi + + if [ "$line3" == "3" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line3 $dest3 <=> $src3" " Out: $out3 | In: $in3" + fi + + if [ "$line4" == "4" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line4 $dest4 <=> $src4" " Out: $out4 | In: $in4" + fi + + if [ "$line5" == "5" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line5 $dest5 <=> $src5" " Out: $out5 | In: $in5" + fi + + if [ "$line6" == "6" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line6 $dest6 <=> $src6" " Out: $out6 | In: $in6" + fi + + if [ "$line7" == "7" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line7 $dest7 <=> $src7" " Out: $out7 | In: $in7" + fi + + if [ "$line8" == "8" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line8 $dest8 <=> $src8" " Out: $out8 | In: $in8" + fi + + if [ "$line9" == "9" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line9 $dest9 <=> $src9" " Out: $out9 | In: $in9" + fi + + if [ "$line10" == "10" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" "$line10 $dest10 <=> $src10" " Out: $out10 | In: $in10" + fi + fi + + if [ "$NCView" = "VPN" ] + then + if [ "$vpn1on" == "True" ] || [ "$vpn2on" == "True" ] || [ "$vpn3on" == "True" ] || [ "$vpn4on" == "True" ] || [ "$vpn5on" == "True" ] || [ "$wg1on" == "True" ] || [ "$wg2on" == "True" ] || [ "$wg3on" == "True" ] || [ "$wg4on" == "True" ] || [ "$wg5on" == "True" ]; then + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} View ${CGreen}(W)${CWhite}AN ${CWhite}| ${CGreen}(L)${CWhite}AN | ${InvDkGray} ${CGreen}(V)${CWhite}PN ${CClear} ${CWhite}| W${CGreen}(G)${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo "" + + slot=0 + while [ "$slot" -ne 5 ] + do + slot="$((slot+1))" + selectedslot="vpn${slot}on" + eval selectedslot="\$${selectedslot}" + if [ "$selectedslot" = "True" ] && [ "$VPNSite2Site" = "0" ] + then + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} VPN$slot ${CClear}" + + vpnsegments1=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==7 {print $1, $2, $4} NR==8 {print $1, $3}') + + line1="$(echo $vpnsegments1 | awk '{print $1}')" + dest1="$(echo $vpnsegments1 | awk '{print $2}')" + out1="$(echo $vpnsegments1 | awk '{print $3}')" + src1="$(echo $vpnsegments1 | awk '{print $4}')" + in1="$(echo $vpnsegments1 | awk '{print $5}')" + + vpnsegments2=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==9 {print $1, $2, $4} NR==10 {print $1, $3}') + + line2="$(echo $vpnsegments2 | awk '{print $1}')" + dest2="$(echo $vpnsegments2 | awk '{print $2}')" + out2="$(echo $vpnsegments2 | awk '{print $3}')" + src2="$(echo $vpnsegments2 | awk '{print $4}')" + in2="$(echo $vpnsegments2 | awk '{print $5}')" + + vpnsegments3=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==11 {print $1, $2, $4} NR==12 {print $1, $3}') + + line3="$(echo $vpnsegments3 | awk '{print $1}')" + dest3="$(echo $vpnsegments3 | awk '{print $2}')" + out3="$(echo $vpnsegments3 | awk '{print $3}')" + src3="$(echo $vpnsegments3 | awk '{print $4}')" + in3="$(echo $vpnsegments3 | awk '{print $5}')" + + vpnsegments4=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==13 {print $1, $2, $4} NR==14 {print $1, $3}') + + line4="$(echo $vpnsegments4 | awk '{print $1}')" + dest4="$(echo $vpnsegments4 | awk '{print $2}')" + out4="$(echo $vpnsegments4 | awk '{print $3}')" + src4="$(echo $vpnsegments4 | awk '{print $4}')" + in4="$(echo $vpnsegments4 | awk '{print $5}')" + + vpnsegments5=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==15 {print $1, $2, $4} NR==16 {print $1, $3}') + + line5="$(echo $vpnsegments5 | awk '{print $1}')" + dest5="$(echo $vpnsegments5 | awk '{print $2}')" + out5="$(echo $vpnsegments5 | awk '{print $3}')" + src5="$(echo $vpnsegments5 | awk '{print $4}')" + in5="$(echo $vpnsegments5 | awk '{print $5}')" + + vpnsegments6=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==17 {print $1, $2, $4} NR==18 {print $1, $3}') + + line6="$(echo $vpnsegments6 | awk '{print $1}')" + dest6="$(echo $vpnsegments6 | awk '{print $2}')" + out6="$(echo $vpnsegments6 | awk '{print $3}')" + src6="$(echo $vpnsegments6 | awk '{print $4}')" + in6="$(echo $vpnsegments6 | awk '{print $5}')" + + vpnsegments7=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==19 {print $1, $2, $4} NR==20 {print $1, $3}') + + line7="$(echo $vpnsegments7 | awk '{print $1}')" + dest7="$(echo $vpnsegments7 | awk '{print $2}')" + out7="$(echo $vpnsegments7 | awk '{print $3}')" + src7="$(echo $vpnsegments7 | awk '{print $4}')" + in7="$(echo $vpnsegments7 | awk '{print $5}')" + + vpnsegments8=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==21 {print $1, $2, $4} NR==22 {print $1, $3}') + + line8="$(echo $vpnsegments8 | awk '{print $1}')" + dest8="$(echo $vpnsegments8 | awk '{print $2}')" + out8="$(echo $vpnsegments8 | awk '{print $3}')" + src8="$(echo $vpnsegments8 | awk '{print $4}')" + in8="$(echo $vpnsegments8 | awk '{print $5}')" + + vpnsegments9=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==23 {print $1, $2, $4} NR==24 {print $1, $3}') + + line9="$(echo $vpnsegments9 | awk '{print $1}')" + dest9="$(echo $vpnsegments9 | awk '{print $2}')" + out9="$(echo $vpnsegments9 | awk '{print $3}')" + src9="$(echo $vpnsegments9 | awk '{print $4}')" + in9="$(echo $vpnsegments9 | awk '{print $5}')" + + vpnsegments10=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==25 {print $1, $2, $4} NR==26 {print $1, $3}') + + line10="$(echo $vpnsegments10 | awk '{print $1}')" + dest10="$(echo $vpnsegments10 | awk '{print $2}')" + out10="$(echo $vpnsegments10 | awk '{print $3}')" + src10="$(echo $vpnsegments10 | awk '{print $4}')" + in10="$(echo $vpnsegments10 | awk '{print $5}')" + + if [ "$line1" == "1" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line1 $dest1 <=> $src1" " Out: $out1 | In: $in1" + else + echo "No Data" + fi + + if [ "$line2" == "2" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line2 $dest2 <=> $src2" " Out: $out2 | In: $in2" + fi + + if [ "$line3" == "3" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line3 $dest3 <=> $src3" " Out: $out3 | In: $in3" + fi + + if [ "$line4" == "4" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line4 $dest4 <=> $src4" " Out: $out4 | In: $in4" + fi + + if [ "$line5" == "5" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line5 $dest5 <=> $src5" " Out: $out5 | In: $in5" + fi + + if [ "$line6" == "6" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line6 $dest6 <=> $src6" " Out: $out6 | In: $in6" + fi + + if [ "$line7" == "7" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line7 $dest7 <=> $src7" " Out: $out7 | In: $in7" + fi + + if [ "$line8" == "8" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line8 $dest8 <=> $src8" " Out: $out8 | In: $in8" + fi + + if [ "$line9" == "9" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line9 $dest9 <=> $src9" " Out: $out9 | In: $in9" + fi + + if [ "$line10" == "10" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" "$line10 $dest10 <=> $src10" " Out: $out10 | In: $in10" + fi + + echo "" + fi + done + fi + fi + +if [ "$NCView" = "WG" ] + then + if [ "$vpn1on" == "True" ] || [ "$vpn2on" == "True" ] || [ "$vpn3on" == "True" ] || [ "$vpn4on" == "True" ] || [ "$vpn5on" == "True" ] || [ "$wg1on" == "True" ] || [ "$wg2on" == "True" ] || [ "$wg3on" == "True" ] || [ "$wg4on" == "True" ] || [ "$wg5on" == "True" ]; then + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} View ${CGreen}(W)${CWhite}AN ${CWhite}| ${CGreen}(L)${CWhite}AN | ${CGreen}(V)${CWhite}PN | ${InvDkGray} W${CGreen}(G) ${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo "" + + slot=0 + while [ "$slot" -ne 5 ] + do + slot="$((slot+1))" + selectedslot="wg${slot}on" + eval selectedslot="\$${selectedslot}" + if [ "$selectedslot" = "True" ] && [ "$VPNSite2Site" = "0" ] + then + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} WG$slot ${CClear}" + + wgsegments1=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==7 {print $1, $2, $4} NR==8 {print $1, $3}') + + line1="$(echo $wgsegments1 | awk '{print $1}')" + dest1="$(echo $wgsegments1 | awk '{print $2}')" + out1="$(echo $wgsegments1 | awk '{print $3}')" + src1="$(echo $wgsegments1 | awk '{print $4}')" + in1="$(echo $wgsegments1 | awk '{print $5}')" + + wgsegments2=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==9 {print $1, $2, $4} NR==10 {print $1, $3}') + + line2="$(echo $wgsegments2 | awk '{print $1}')" + dest2="$(echo $wgsegments2 | awk '{print $2}')" + out2="$(echo $wgsegments2 | awk '{print $3}')" + src2="$(echo $wgsegments2 | awk '{print $4}')" + in2="$(echo $wgsegments2 | awk '{print $5}')" + + wgsegments3=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==11 {print $1, $2, $4} NR==12 {print $1, $3}') + + line3="$(echo $wgsegments3 | awk '{print $1}')" + dest3="$(echo $wgsegments3 | awk '{print $2}')" + out3="$(echo $wgsegments3 | awk '{print $3}')" + src3="$(echo $wgsegments3 | awk '{print $4}')" + in3="$(echo $wgsegments3 | awk '{print $5}')" + + wgsegments4=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==13 {print $1, $2, $4} NR==14 {print $1, $3}') + + line4="$(echo $wgsegments4 | awk '{print $1}')" + dest4="$(echo $wgsegments4 | awk '{print $2}')" + out4="$(echo $wgsegments4 | awk '{print $3}')" + src4="$(echo $wgsegments4 | awk '{print $4}')" + in4="$(echo $wgsegments4 | awk '{print $5}')" + + wgsegments5=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==15 {print $1, $2, $4} NR==16 {print $1, $3}') + + line5="$(echo $wgsegments5 | awk '{print $1}')" + dest5="$(echo $wgsegments5 | awk '{print $2}')" + out5="$(echo $wgsegments5 | awk '{print $3}')" + src5="$(echo $wgsegments5 | awk '{print $4}')" + in5="$(echo $wgsegments5 | awk '{print $5}')" + + wgsegments6=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==17 {print $1, $2, $4} NR==18 {print $1, $3}') + + line6="$(echo $wgsegments6 | awk '{print $1}')" + dest6="$(echo $wgsegments6 | awk '{print $2}')" + out6="$(echo $wgsegments6 | awk '{print $3}')" + src6="$(echo $wgsegments6 | awk '{print $4}')" + in6="$(echo $wgsegments6 | awk '{print $5}')" + + wgsegments7=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==19 {print $1, $2, $4} NR==20 {print $1, $3}') + + line7="$(echo $wgsegments7 | awk '{print $1}')" + dest7="$(echo $wgsegments7 | awk '{print $2}')" + out7="$(echo $wgsegments7 | awk '{print $3}')" + src7="$(echo $wgsegments7 | awk '{print $4}')" + in7="$(echo $wgsegments7 | awk '{print $5}')" + + wgsegments8=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==21 {print $1, $2, $4} NR==22 {print $1, $3}') + + line8="$(echo $wgsegments8 | awk '{print $1}')" + dest8="$(echo $wgsegments8 | awk '{print $2}')" + out8="$(echo $wgsegments8 | awk '{print $3}')" + src8="$(echo $wgsegments8 | awk '{print $4}')" + in8="$(echo $wgsegments8 | awk '{print $5}')" + + wgsegments9=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==23 {print $1, $2, $4} NR==24 {print $1, $3}') + + line9="$(echo $wgsegments9 | awk '{print $1}')" + dest9="$(echo $wgsegments9 | awk '{print $2}')" + out9="$(echo $wgsegments9 | awk '{print $3}')" + src9="$(echo $wgsegments9 | awk '{print $4}')" + in9="$(echo $wgsegments9 | awk '{print $5}')" + + wgsegments10=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==25 {print $1, $2, $4} NR==26 {print $1, $3}') + + line10="$(echo $wgsegments10 | awk '{print $1}')" + dest10="$(echo $wgsegments10 | awk '{print $2}')" + out10="$(echo $wgsegments10 | awk '{print $3}')" + src10="$(echo $wgsegments10 | awk '{print $4}')" + in10="$(echo $wgsegments10 | awk '{print $5}')" + + if [ "$line1" == "1" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line1 $dest1 <=> $src1" " Out: $out1 | In: $in1" + else + echo "No Data" + fi + + if [ "$line2" == "2" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line2 $dest2 <=> $src2" " Out: $out2 | In: $in2" + fi + + if [ "$line3" == "3" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line3 $dest3 <=> $src3" " Out: $out3 | In: $in3" + fi + + if [ "$line4" == "4" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line4 $dest4 <=> $src4" " Out: $out4 | In: $in4" + fi + + if [ "$line5" == "5" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line5 $dest5 <=> $src5" " Out: $out5 | In: $in5" + fi + + if [ "$line6" == "6" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line6 $dest6 <=> $src6" " Out: $out6 | In: $in6" + fi + + if [ "$line7" == "7" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line7 $dest7 <=> $src7" " Out: $out7 | In: $in7" + fi + + if [ "$line8" == "8" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line8 $dest8 <=> $src8" " Out: $out8 | In: $in8" + fi + + if [ "$line9" == "9" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" " $line9 $dest9 <=> $src9" " Out: $out9 | In: $in9" + fi + + if [ "$line10" == "10" ]; then + printf "${CWhite}%-82s${CGreen}%s\n" "$line10 $dest10 <=> $src10" " Out: $out10 | In: $in10" + fi + + echo "" + fi + done + fi + fi + +} + +# ------------------------------------------------------------------------------------------------------------------------- +##------------------------------------------## +## Modified by ExtremeFiretop [2024-Aug-06] ## +##------------------------------------------## +# This function displays the stats UI for page 3 +DisplayPage7() +{ + clear + if [ "$UpdateNotify" != "0" ]; then + echo -e "$UpdateNotify${CClear}" + fi + showheader + # Create a temp arp table of connected wifi/lan clients + cat /proc/net/arp > /jffs/addons/rtrmon.d/temparp.txt + + # Force create the processed clients list file + touch /jffs/addons/rtrmon.d/processed_clients.txt + # Force create the processed clients list file for VLAN + touch /jffs/addons/rtrmon.d/processed_vlanclients.txt + + # Per @Stephen Harrington's sugguestion, check NVRAM to see if Wifi is turned on, else mark them as disabled + if [ "$FourBandCustom55624" == "True" ]; then + if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then + MaxSpeed52GhzNow=0 + else + MaxSpeed52GhzNow=$MaxSpeed5Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then + MaxSpeed6GhzNow=0 + else + MaxSpeed6GhzNow=$MaxSpeed6Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl3_radio) -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + elif [ "$FourBandCustom56624" == "True" ]; then + if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then + MaxSpeed6GhzNow=0 + else + MaxSpeed6GhzNow=$MaxSpeed6Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then + MaxSpeed62GhzNow=0 + else + MaxSpeed62GhzNow=$MaxSpeed6Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl3_radio) -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + elif [ "$ThreeBand2456" == "True" ]; then + if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then + MaxSpeed6GhzNow=0 + else + MaxSpeed6GhzNow=$MaxSpeed6Ghz + fi + elif [ "$ThreeBand2455" == "True" ]; then + if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then + MaxSpeed52GhzNow=0 + else + MaxSpeed52GhzNow=$MaxSpeed5Ghz + fi + else + if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + fi + + if [ "$SortbyOpt" = "Name" ]; then + SortbyNum="1" + elif [ "$SortbyOpt" = "IP" ]; then + SortbyNum="2" + elif [ "$SortbyOpt" = "MAC" ]; then + SortbyNum="3" + else + SortbyNum="1" + fi + prevSortByOpt="$SortbyOpt" + + #Testing + #MaxSpeed24GhzNow=0 + #w24updown="UP" #testing + echo "" + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} Attached Wireless + Wired Clients ${CClear}" + if [ "$SortbyOpt" = "Name" ]; then + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} Sort By: ${InvDkGray}${CGreen} (!)${CWhite}Name ${CClear}${CWhite} | ${CGreen}(@)${CWhite}IP | ${CGreen}(#)${CWhite}MAC${CClear}" + elif [ "$SortbyOpt" = "IP" ]; then + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} Sort By: ${CGreen} (!)${CWhite}Name | ${InvDkGray} ${CGreen}(@)${CWhite}IP ${CClear}${CWhite} | ${CGreen}(#)${CWhite}MAC${CClear}" + elif [ "$SortbyOpt" = "MAC" ]; then + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} Sort By: ${CGreen} (!)${CWhite}Name | ${CGreen}(@)${CWhite}IP | ${InvDkGray} ${CGreen}(#)${CWhite}MAC ${CClear}" + fi + echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo "" + + if [ "$MaxSpeed24GhzNow" != "0" ]; then + if [ "$w24updown" == "UP" ]; then + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 2.4GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname24 ${CClear}" + else + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 2.4GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname24 ${CClear}" + fi + attachedwificlients "$ifname24" + echo "" + else + echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 2.4GHz ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" + echo "" + fi + #Testing + #MaxSpeed5GhzNow=0 #testing + #w5updown="UP" #testing + if [ "$MaxSpeed5GhzNow" != "0" ]; then + if [ "$w5updown" == "UP" ]; then + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname5 ${CClear}" + else + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname5 ${CClear}" + fi + attachedwificlients "$ifname5" + echo "" + else + echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" + echo "" + fi + #Testing + #FourBandCustom55624="True" #testing + #MaxSpeed52GhzNow=0 #testing + #w52updown="UP" #testing + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then + if [ "$MaxSpeed52GhzNow" != "0" ]; then + if [ "$w52updown" == "UP" ]; then + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz (2) ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname52 ${CClear}" + else + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz (2) ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname52 ${CClear}" + fi + attachedwificlients "$ifname52" + #attachedwificlients "$ifname5" #testing + echo "" + else + echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz (2) ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" + echo "" + fi + fi + #Testing + #ThreeBand2456="True" #testing + #MaxSpeed6GhzNow=1 #testing + #w6updown="UP" #testing + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then + if [ "$MaxSpeed6GhzNow" != "0" ]; then + if [ "$w6updown" == "UP" ]; then + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname6 ${CClear}" + else + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname6 ${CClear}" + fi + attachedwificlients "$ifname6" + #attachedwificlients "$ifname5" #testing + echo "" + else + echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" + echo "" + fi + fi + #Testing + #FourBandCustom56624="True" #testing + #MaxSpeed62GhzNow=0 #testing + #w62updown="UP" #testing + if [ "$FourBandCustom56624" == "True" ]; then + if [ "$MaxSpeed62GhzNow" != "0" ]; then + if [ "$w62updown" == "UP" ]; then + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz (2) ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname62 ${CClear}" + else + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz (2) ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname62 ${CClear}" + fi + attachedwificlients "$ifname62" + #attachedwificlients "$ifname5" #testing + echo "" + else + echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz (2) ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" + echo "" + fi + fi + + # Guest Network Clients - Thanks to @ColinTaylor for this methodology of stepping through legit guest network interfaces + cp -f /jffs/addons/rtrmon.d/temparp.txt /jffs/addons/rtrmon.d/temparpvlan.txt + for guestiface in $(nvram get wl0_vifs) $(nvram get wl1_vifs) $(nvram get wl2_vifs) $(nvram get wl3_vifs) + do + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local Guest Wi-Fi ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $guestiface ${CClear}" + attachedguestclients "$guestiface" + echo "" + done + + for vlanlabels in $(nvram get apg_ifnames) + do + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local VLAN/AiMesh VLAN ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $vlanlabels ${CClear}" + attachedvlanclients "$vlanlabels" + echo "" + done + + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local LAN/Non-VLAN AiMesh ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: br0 ${CClear}" + #Remove non-LAN records + sed -i -e '/eth0/d' /jffs/addons/rtrmon.d/temparp.txt + sed -i -e '/IP address/d' /jffs/addons/rtrmon.d/temparp.txt + sed -i -e '/00:00:00:00:00:00/d' /jffs/addons/rtrmon.d/temparp.txt + sed -i -e '/0x0/d' /jffs/addons/rtrmon.d/temparp.txt + attachedlanclients + rm -f /jffs/addons/rtrmon.d/processed_clients.txt + rm -f /jffs/addons/rtrmon.d/processed_vlanclients.txt + rm -f /jffs/addons/rtrmon.d/temparp.txt + + #Testing + #FourBandCustom55624="False" #testing + #MaxSpeed52GhzNow=0 #testing + #w52updown="UP" #testing + #ThreeBand2456="False" #testing + #MaxSpeed6GhzNow=0 #testing + #w6updown="UP" #testing + #FourBandCustom56624="False" #testing + #MaxSpeed62GhzNow=0 #testing + #w62updown="UP" #testing +} + +# ------------------------------------------------------------------------------------------------------------------------- +# multiple DHCP lists can exist. Read through all lists and compile into a single list. + +read_all_dhcp_leases() { + # Include the merged lease file if it exists + local lease_files="/var/lib/misc/dnsmasq-*.leases /var/lib/misc/dnsmasq.leases" + if [ -f "/tmp/dnsmasq-merged.leases" ]; then + lease_files="$lease_files /tmp/dnsmasq-merged.leases" + fi + local all_leases + all_leases=$(cat $lease_files 2>/dev/null) + echo "$all_leases" +} + +# Unified MLD MAC retrieval logic: given the current dhcpleases and association MAC (in lowercase), +# determine the lookup MAC (which may be the MLD MAC if present). +get_lookup_mac() { + local maclower="$1" + local leases="$2" + local lookup_mac="$maclower" + local mld_line field_count mld_mac + mld_line=$(echo "$leases" | grep -i "$maclower" | head -n1) + if [ -n "$mld_line" ]; then + field_count=$(echo "$mld_line" | awk '{print NF; exit}') + if [ "$field_count" -ge 5 ]; then + mld_mac=$(echo "$mld_line" | awk '{print $5; exit}') + if [ -n "$mld_mac" ] && [ "$mld_mac" != "*" ]; then + lookup_mac=$(echo "$mld_mac" | awk '{print tolower($0)}') + fi + fi + fi + echo "$lookup_mac" +} + +# attachedwificlients pulls connected client info from wl, arp and nvram +attachedwificlients () +{ + iface="$1" + rm -f /jffs/addons/rtrmon.d/wificlients$iface.txt + wl -i $iface assoclist > /jffs/addons/rtrmon.d/wificlients$iface.txt + maxclientcount=$(cat /jffs/addons/rtrmon.d/wificlients$iface.txt | wc -l) + rm -f /jffs/addons/rtrmon.d/clientlist$iface.txt + dhcpleases="$(read_all_dhcp_leases)" + local clients=$(nvram get custom_clientlist) + local maxextractcount=$(echo "$clients" | awk -F'>>' '{count=0; for (i=1; i<=NF; i++) if ($i != "") count++; print count}') + + local clientcount=0 + while [ $clientcount -le $maxclientcount ] + do + clientname="" + conntime="" + clientip="" + paddedclientip="" + clientcount=$((clientcount+1)) + local clientmac=$(awk 'NR=='$clientcount' {print $2}' /jffs/addons/rtrmon.d/wificlients$iface.txt) + + if [ -z "$clientmac" ]; then + continue + fi + + networktime=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/in network/ {print $3}') 2>/dev/null + conntime=$(date -d@$networktime -u +%Hh:%Mm) 2>/dev/null + txtotalbytes=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/tx total bytes:/ {print $4}') 2>/dev/null + rxtotalbytes=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rx data bytes:/ {print $4}') 2>/dev/null + txratekbps=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rate of last tx pkt:/ {print $6}') 2>/dev/null + rxratekbps=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rate of last rx pkt:/ {print $6}') 2>/dev/null + sigstrength=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/smoothed rssi:/ {print $3}') 2>/dev/null + maclower=$(echo "$clientmac" | awk '{print tolower($0)}') 2>/dev/null + + # --- Unified MLD MAC retrieval logic --- + lookup_mac=$(get_lookup_mac "$maclower" "$dhcpleases") + + # Find IPs for the given MAC address in the ARP table + ips=$(grep "$maclower" "/jffs/addons/rtrmon.d/temparp.txt" | awk '{print $1}') 2>/dev/null + + # Iterate over the IPs to find the reachable one + for ip in $ips; do + # Check the status of the IP in the neighbor table + arp_status=$(ip neigh show | grep -w "$ip" | awk '{print $NF}') 2>/dev/null + + # Check if the current IP is reachable + if [ -z "$arp_status" ] || { [ "$arp_status" != "REACHABLE" ] && [ "$arp_status" != "DELAY" ]; }; then + if [ -z "$sigstrength" ]; then + conntime="STALE" + fi + continue + else + # Set the clientip to the current IP if it is reachable or delay + clientip="$ip" + break + fi + done + + # Fallback to using the ARP table if no reachable IP was found + if [ -z "$clientip" ]; then + clientip=$(cat /proc/net/arp | grep "$maclower" | awk '{print $1}' | sort | uniq | tail -n 1) 2>/dev/null + fi + + paddedclientip=$(echo "${clientip}" | grep -o -E '([0-9]*\.|[0-9]*)' | awk '{printf( "%03d\n", $1)}' | tr '\n' '.' | sed 's/.$//') 2>/dev/null + + #calcs + txtotalgb=$(echo $txtotalbytes | awk -v txb=$txtotalbytes 'BEGIN{printf "%0.2f\n", txb/1024/1024/1024}') 2>/dev/null + rxtotalgb=$(echo $rxtotalbytes | awk -v rxb=$rxtotalbytes 'BEGIN{printf "%0.2f\n", rxb/1024/1024/1024}') 2>/dev/null + txratembps=$(echo $txratekbps | awk -v txm=$txratekbps 'BEGIN{printf "%0.1f\n", txm/1000}') 2>/dev/null + rxratembps=$(echo $rxratekbps | awk -v rxm=$rxratekbps 'BEGIN{printf "%0.1f\n", rxm/1000}') 2>/dev/null + + local found=0 + local counter=0 + while [ $counter -le $maxextractcount ] + do + counter=$((counter+1)) + local clientextract="$(echo $clients | cut -d "<" -f$counter | cut -d ">" -f1,2)" + + if [ -z "$clientextract" ]; then + break + fi + + local client="$(echo $clientextract | awk -F ">" '{print $1}')" + local mac="$(echo $clientextract | awk -F ">" '{print $2}')" + + if [ "$mac" == "$clientmac" ]; then + clientname=$client + found=1 + break + fi + done + # Fallback to using dnsmasq.leases if no match found + if [ $found -ne 1 ]; then + clientname=$(echo "$dhcpleases" | grep -i "$lookup_mac" | awk '{print $4}') 2>/dev/null + if [ -z "$clientname" ] || [ "$clientname" == "*" ]; then + clientname="UNKNOWN" + fi + fi + if [ -n "$paddedclientip" ] && [ "$paddedclientip" != "000.000.000.000" ]; then + # Add the check for already processed clients + if grep -qi "$clientmac" /jffs/addons/rtrmon.d/processed_clients.txt; then + # Skip processing if the device was already handled + continue + else + echo "$clientmac" >> /jffs/addons/rtrmon.d/processed_clients.txt + fi + #delete entry from temparp table + sed -i -e '/'$maclower'/d' /jffs/addons/rtrmon.d/temparp.txt + echo "$clientname,$paddedclientip,$clientmac,$conntime,$txtotalgb,$rxtotalgb,$txratembps,$rxratembps,$sigstrength" >> /jffs/addons/rtrmon.d/clientlist$iface.txt + fi + done + + if [ -f "/jffs/addons/rtrmon.d/clientlist$iface.txt" ]; then + if [ $maxclientcount -ge 1 ]; then + sort -f -d -o /jffs/addons/rtrmon.d/clientlist$iface.txt -k "$SortbyNum" -t , /jffs/addons/rtrmon.d/clientlist$iface.txt 2>/dev/null + column -t -s',' -o' | ' -N Name,IP,MAC,Uptime,"TX GB","RX GB","TX Mbps","RX Mbps","Sig" /jffs/addons/rtrmon.d/clientlist$iface.txt | sed 's/^/ /' + else + echo -e " No Devices Connected" + fi + else + echo -e " No Devices Connected" + fi +} + +# ------------------------------------------------------------------------------------------------------------------------- +# attachedguestclients pulls connected client info from wl, arp and nvram +##------------------------------------------## +## Modified by ExtremeFiretop [2024-Aug-06] ## +##------------------------------------------## +attachedguestclients() { + iface="$1" + rm -f /jffs/addons/rtrmon.d/wificlients$iface.txt + wl -i $iface assoclist > /jffs/addons/rtrmon.d/wificlients$iface.txt + maxclientcount=$(cat /jffs/addons/rtrmon.d/wificlients$iface.txt | wc -l) + rm -f /jffs/addons/rtrmon.d/clientlist$iface.txt + dhcpleases="$(read_all_dhcp_leases)" + local clients=$(nvram get custom_clientlist) + local maxextractcount=$(echo "$clients" | awk -F'>>' '{count=0; for (i=1; i<=NF; i++) if ($i != "") count++; print count}') + + local clientcount=0 + while [ $clientcount -le $maxclientcount ] + do + clientname="" + conntime="" + clientip="" + paddedclientip="" + clientcount=$((clientcount+1)) + local clientmac=$(awk 'NR=='$clientcount' {print $2}' /jffs/addons/rtrmon.d/wificlients$iface.txt) + + if [ -z "$clientmac" ]; then + continue + fi + + networktime=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/in network/ {print $3}') 2>/dev/null + conntime=$(date -d@$networktime -u +%Hh:%Mm) 2>/dev/null + txtotalbytes=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/tx total bytes:/ {print $4}') 2>/dev/null + rxtotalbytes=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rx data bytes:/ {print $4}') 2>/dev/null + txratekbps=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rate of last tx pkt:/ {print $6}') 2>/dev/null + rxratekbps=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rate of last rx pkt:/ {print $6}') 2>/dev/null + sigstrength=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/smoothed rssi:/ {print $3}') 2>/dev/null + maclower=$(echo "$clientmac" | awk '{print tolower($0)}') 2>/dev/null + # --- Unified MLD MAC retrieval logic --- + lookup_mac=$(get_lookup_mac "$maclower" "$dhcpleases") + + # Find IPs for the given MAC address in the ARP table + ips=$(grep "$maclower" "/jffs/addons/rtrmon.d/temparp.txt" | awk '{print $1}') 2>/dev/null + + # Iterate over the IPs to find the reachable one + for ip in $ips; do + # Check the status of the IP in the neighbor table + arp_status=$(ip neigh show | grep -w "$ip" | awk '{print $NF}') 2>/dev/null + + # Check if the current IP is reachable + if [ -z "$arp_status" ] || { [ "$arp_status" != "REACHABLE" ] && [ "$arp_status" != "DELAY" ]; }; then + if [ -z "$sigstrength" ]; then + conntime="STALE" + fi + continue + else + # Set the clientip to the current IP if it is reachable or delay + clientip="$ip" + break + fi + done + + # Fallback to using the ARP table or DHCP leases if no reachable IP was found + if [ -z "$clientip" ]; then + # Try to get the last IP from the ARP table + clientip=$(cat /proc/net/arp | grep "$maclower" | awk '{print $1}' | sort | uniq | tail -n 1) 2>/dev/null + fi + + paddedclientip=$(echo "${clientip}" | grep -o -E '([0-9]*\.|[0-9]*)' | awk '{printf( "%03d\n", $1)}' | tr '\n' '.' | sed 's/.$//') 2>/dev/null + + #calcs + txtotalgb=$(echo $txtotalbytes | awk '{printf "%0.2f", $1/1024/1024/1024}') 2>/dev/null + rxtotalgb=$(echo $rxtotalbytes | awk '{printf "%0.2f", $1/1024/1024/1024}') 2>/dev/null + txratembps=$(echo $txratekbps | awk '{printf "%0.1f", $1/1000}') 2>/dev/null + rxratembps=$(echo $rxratekbps | awk '{printf "%0.1f", $1/1000}') 2>/dev/null + + local found=0 + local counter=0 + while [ $counter -le $maxextractcount ] + do + counter=$((counter+1)) + local clientextract="$(echo $clients | cut -d "<" -f$counter | cut -d ">" -f1,2)" + + if [ -z "$clientextract" ]; then + break + fi + + local client=$(echo $clientextract | awk -F ">" '{print $1}') + local mac=$(echo $clientextract | awk -F ">" '{print $2}') + + if [ "$mac" == "$clientmac" ]; then + clientname=$client + found=1 + break + fi + done + # Fallback to using dnsmasq.leases if no match found + if [ $found -ne 1 ]; then + clientname=$(echo "$dhcpleases" | grep -i "$lookup_mac" | awk '{print $4}') 2>/dev/null + if [ -z "$clientname" ] || [ "$clientname" == "*" ]; then + clientname="UNKNOWN" + fi + fi + if [ -n "$paddedclientip" ] && [ "$paddedclientip" != "000.000.000.000" ]; then + # Add the check for already processed clients + if grep -qi "$clientmac" /jffs/addons/rtrmon.d/processed_clients.txt; then + # Skip processing if the device was already handled + continue + else + echo "$clientmac" >> /jffs/addons/rtrmon.d/processed_clients.txt + fi + #delete entry from temparp table + sed -i -e '/'$maclower'/d' /jffs/addons/rtrmon.d/temparp.txt + echo "$clientname,$paddedclientip,$clientmac,$conntime,$txtotalgb,$rxtotalgb,$txratembps,$rxratembps,$sigstrength" >> /jffs/addons/rtrmon.d/clientlist$iface.txt + fi + done + + if [ -f "/jffs/addons/rtrmon.d/clientlist$iface.txt" ]; then + if [ $maxclientcount -ge 1 ]; then + sort -f -d -o /jffs/addons/rtrmon.d/clientlist$iface.txt -k "$SortbyNum" -t , /jffs/addons/rtrmon.d/clientlist$iface.txt 2>/dev/null + column -t -s',' -o' | ' -N Name,IP,MAC,Uptime,"TX GB","RX GB","TX Mbps","RX Mbps","Sig" /jffs/addons/rtrmon.d/clientlist$iface.txt | sed 's/^/ /' + else + echo -e " No Devices Connected" + fi + else + echo -e " No Devices Connected" + fi +} + +# ------------------------------------------------------------------------------------------------------------------------- +# attachedvlanclients pulls connected client info from wl, arp and nvram + +attachedvlanclients() { + iface="$1" + vlansfound=1 + maxclientcount=$(cat /jffs/addons/rtrmon.d/temparpvlan.txt | wc -l) + rm -f /jffs/addons/rtrmon.d/vlanclients$iface.txt + dhcpleases="$(read_all_dhcp_leases)" + local clients=$(nvram get custom_clientlist) + local maxextractcount=$(echo "$clients" | awk -F'>>' '{count=0; for (i=1; i<=NF; i++) if ($i != "") count++; print count}') + + local clientcount=0 + while [ $clientcount -le $maxclientcount ] + do + clientname="" + conntime="" + clientip="" + paddedclientip="" + interface_name="" + clientcount=$((clientcount+1)) + local clientmac=$(awk 'NR=='$clientcount' {print $4}' /jffs/addons/rtrmon.d/temparpvlan.txt | xargs) + + if [ -z "$clientmac" ]; then + continue + fi + + # Convert the MAC address to uppercase and store it in a new variable + macupper=$(echo "$clientmac" | tr 'a-f' 'A-F') + macprefix=$(echo "$macupper" | awk -F ':' '{print $1":"$2":"$3":"$4":"$5}') 2>/dev/null + clientbridgeid=$(awk 'NR=='$clientcount' {print $6}' /jffs/addons/rtrmon.d/temparpvlan.txt | xargs) + if [ -z "$clientbridgeid" ] || [ "$clientbridgeid" != "$iface" ]; then + continue + else + vlansfound=0 + fi + + interfaces=$(ip link show | grep -E 'wl|wlan' | awk -F: '{print $2}' | tr -d ' ') + for wirelessface in $interfaces; do + # Suppress both standard output and error from the wl command and check for the MAC + if wl -i "$wirelessface" assoclist 2>/dev/null | grep -iq "$macprefix"; then + # Save the interface name into the variable + interface_name="$wirelessface" + continue + fi + done + + networktime=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/in network/ {print $3}') 2>/dev/null + # Set conntime to "OFFLINE" if networktime is empty + if [ -z "$networktime" ]; then + conntime="AiMesh" + else + conntime=$(date -d@$networktime -u +%Hh:%Mm) 2>/dev/null + fi + txtotalbytes=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/tx total bytes:/ {print $4}') 2>/dev/null + rxtotalbytes=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/rx data bytes:/ {print $4}') 2>/dev/null + txratekbps=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/rate of last tx pkt:/ {print $6}') 2>/dev/null + rxratekbps=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/rate of last rx pkt:/ {print $6}') 2>/dev/null + sigstrength=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/smoothed rssi:/ {print $3}') 2>/dev/null + + # --- Unified MLD MAC lookup for VLAN clients --- + maclower=$(echo "$clientmac" | awk '{print tolower($0)}') 2>/dev/null + lookup_mac=$(get_lookup_mac "$maclower" "$dhcpleases") + + # Find IPs for the given MAC address in the ARP table + ips=$(grep "$clientmac" "/jffs/addons/rtrmon.d/temparp.txt" | awk '{print $1}') 2>/dev/null + + # Iterate over the IPs to find the reachable one + for ip in $ips; do + # Check the status of the IP in the neighbor table + arp_status=$(ip neigh show | grep -w "$ip" | awk '{print $NF}') 2>/dev/null + + # Check if the current IP is reachable + if [ -z "$arp_status" ] || { [ "$arp_status" != "REACHABLE" ] && [ "$arp_status" != "DELAY" ]; }; then + if [ -z "$sigstrength" ]; then + conntime="STALE" + fi + continue + else + # Set the clientip to the current IP if it is reachable or delay + clientip="$ip" + break + fi + done + + # Fallback to using the ARP table if no reachable IP was found + if [ -z "$clientip" ]; then + clientip=$(cat /proc/net/arp | grep "$clientmac" | awk '{print $1}' | sort | uniq | tail -n 1) 2>/dev/null + fi + + paddedclientip=$(echo "$clientip" | awk -F '.' '{printf "%03d.%03d.%03d.%03d\n", $1, $2, $3, $4}') 2>/dev/null + + #calcs + txtotalgb=$(echo $txtotalbytes | awk '{printf "%0.2f", $1/1024/1024/1024}') 2>/dev/null + rxtotalgb=$(echo $rxtotalbytes | awk '{printf "%0.2f", $1/1024/1024/1024}') 2>/dev/null + txratembps=$(echo $txratekbps | awk '{printf "%0.1f", $1/1000}') 2>/dev/null + rxratembps=$(echo $rxratekbps | awk '{printf "%0.1f", $1/1000}') 2>/dev/null + + local found=0 + local counter=0 + while [ $counter -le $maxextractcount ] + do + counter=$((counter+1)) + local clientextract="$(echo $clients | cut -d "<" -f$counter | cut -d ">" -f1,2)" + + if [ -z "$clientextract" ]; then + break + fi + + local client="$(echo $clientextract | awk -F ">" '{print $1}')" + local mac="$(echo $clientextract | awk -F ">" '{print $2}')" + + if [ "$mac" == "$macupper" ]; then + clientname=$client + found=1 + break + fi + + done + # Fallback to using dnsmasq.leases if no match found + if [ $found -ne 1 ]; then + clientname=$(echo "$dhcpleases" | grep -i "$lookup_mac" | awk '{print $4}') 2>/dev/null + if [ -z "$clientname" ] || [ "$clientname" == "*" ]; then + clientname="UNKNOWN" + fi + fi + if [ -n "$paddedclientip" ] && [ "$paddedclientip" != "000.000.000.000" ]; then + # Check if this MAC address has already been processed + if grep -q "$macupper" /jffs/addons/rtrmon.d/processed_vlanclients.txt && [ "$conntime" = "STALE" ]; then + continue # Skip processing this MAC address + else + # Mark this MAC as processed by adding it to the processed_macs_file + echo "$macupper" >> /jffs/addons/rtrmon.d/processed_vlanclients.txt + fi + #delete entry from temparp table + sed -i -e '/'$clientmac'/d' /jffs/addons/rtrmon.d/temparp.txt + if [ "$conntime" = "AiMesh" ]; then + echo "$clientname,$paddedclientip,$macupper,$conntime" >> /jffs/addons/rtrmon.d/vlanclients$iface.txt + else + echo "$clientname,$paddedclientip,$macupper,$conntime,$txtotalgb,$rxtotalgb,$txratembps,$rxratembps,$sigstrength" >> /jffs/addons/rtrmon.d/vlanclients$iface.txt + fi + fi + done + + if [ -f "/jffs/addons/rtrmon.d/vlanclients$iface.txt" ]; then + if [ $vlansfound -eq 0 ]; then + sort -f -d -t ',' -k "$SortbyNum" -k 4,4 /jffs/addons/rtrmon.d/vlanclients$iface.txt 2>/dev/null | \ + awk -F',' -v OFS=',' '{if ($4 ~ /AiMesh/) {a[i++]=$0} else {print $0}} END {for (j=0; j /tmp/vlanclients_sorted.txt + # Move sorted file back to original + mv /tmp/vlanclients_sorted.txt /jffs/addons/rtrmon.d/vlanclients$iface.txt + column -t -s',' -o' | ' -N Name,IP,MAC,Uptime,"TX GB","RX GB","TX Mbps","RX Mbps","Sig" /jffs/addons/rtrmon.d/vlanclients$iface.txt | sed 's/^/ /' + else + echo -e " No Devices Connected" + fi + else + echo -e " No Devices Connected" + fi +} + +# ------------------------------------------------------------------------------------------------------------------------- +# attachedlanclients pulls connected client info from wl, arp and nvram + +attachedlanclients () +{ + maxclientcount=$(cat /jffs/addons/rtrmon.d/temparp.txt | wc -l) + rm -f /jffs/addons/rtrmon.d/clientlistbr0.txt + dhcpleases="$(read_all_dhcp_leases)" + #find matchine client name + local clients=$(nvram get custom_clientlist) + local maxextractcount=$(echo "$clients" | awk -F'>>' '{count=0; for (i=1; i<=NF; i++) if ($i != "") count++; print count}') + + local clientcount=0 + while [ $clientcount -le $maxclientcount ] + do + clientname="" + paddedclientip="" + clientcount=$((clientcount+1)) + local clientmac=$(cat /jffs/addons/rtrmon.d/temparp.txt | awk 'NR=='$clientcount' {print $4}') 2>/dev/null + + if [ -z "$clientmac" ]; then + continue + fi + + local macupper=$(echo "$clientmac" | tr 'a-f' 'A-F') + + # Add the check for already processed clients + if grep -qi "$clients" /jffs/addons/rtrmon.d/processed_clients.txt; then + # Skip processing if the device was already handled + continue + else + echo "$macupper" >> /jffs/addons/rtrmon.d/processed_clients.txt + fi + + local counter=0 + local found=0 + while [ $counter -le $maxextractcount ] + do + counter=$((counter+1)) + local clientextract="$(echo $clients | cut -d "<" -f$counter | cut -d ">" -f1,2)" + + if [ -z "$clientextract" ]; then + continue + fi + + #clientip=$(cat /proc/net/arp | grep $clientmac | awk '{print $1}') + clientip=$(cat /jffs/addons/rtrmon.d/temparp.txt | grep $clientmac | awk '{print $1; exit}') 2>/dev/null + paddedclientip=$(echo "${clientip}" | grep -o -E '([0-9]*\.|[0-9]*)' | awk '{printf( "%03d\n", $1)}' | tr '\n' '.' | sed 's/.$//') 2>/dev/null + if [ -z $paddedclientip ]; then paddedclientip="000.000.000.000"; fi + + local client="$(echo $clientextract | awk -F ">" '{print $1}')" + local mac="$(echo $clientextract | awk -F ">" '{print $2}')" + + if [ "$mac" == "$macupper" ]; then + clientname=$client + found=1 + break + fi + done + # Fallback to using dnsmasq.leases if no match found + if [ $found -ne 1 ]; then + clientname=$(echo "$dhcpleases" | grep -i "$clientmac" | awk '{print $4}') + if [ -z "$clientname" ] || [ "$clientname" == "*" ]; then + clientname="UNKNOWN" + fi + fi + if [ -n "$paddedclientip" ] && [ "$paddedclientip" != "000.000.000.000" ]; then + echo "$clientname,$paddedclientip,$macupper" >> /jffs/addons/rtrmon.d/clientlistbr0.txt + fi + done + + if [ -f "/jffs/addons/rtrmon.d/clientlistbr0.txt" ]; then + if [ $maxclientcount -ge 1 ]; then + sort -f -d -o /jffs/addons/rtrmon.d/clientlistbr0.txt -k "$SortbyNum" -t , /jffs/addons/rtrmon.d/clientlistbr0.txt 2>/dev/null + column -t -s',' -o' | ' -N Name,IP,MAC /jffs/addons/rtrmon.d/clientlistbr0.txt | sed 's/^/ /' + else + echo -e " No Devices Connected" + fi + else + echo -e " No Devices Connected" + fi +} + +# ------------------------------------------------------------------------------------------------------------------------- +# GetVPNWGIPCITY is a function that gathers IP/City stats from all active VPN and WG connections + +GetVPNWGIPCITY() +{ + + vpn1slot=1 + VPN1State="$(_VPN_GetClientState_ ${vpn1slot})" + if [ -z "$VPN1State" ]; then VPN1State=0; fi # to catch possible wireguard interference + if [ "$VPN1State" -eq 2 ]; then + if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing VPN1 Stats...]"; fi + TUN1="tun1"$vpn1slot + NVRAMVPN1ADDR=$($timeoutcmd$timeoutsec nvram get vpn_client"$vpn1slot"_addr) + NVRAMVPN1IP=$(ping -c 1 -w 1 $NVRAMVPN1ADDR | awk -F '[()]' '/PING/ { print $2}') + + if [ "$NVRAMVPN1ADDR" != "$oldvpn1ADDR" ]; then + oldvpn1ip=$(curl --silent --fail --interface $TUN1 --request GET --url https://ipv4.icanhazip.com) + if [ -z $oldvpn1ip ]; then oldvpn1ip=$NVRAMVPN1IP; fi + oldvpn1ADDR=$NVRAMVPN1ADDR + fi + + if [ "$(echo $NVRAMVPN1IP | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then + oldvpn1ip=$NVRAMVPN1IP + oldvpn1city="Private Network" + elif [ "$vpn1ip" != "$oldvpn1ip" ]; then + oldvpn1city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldvpn1ip | jq --raw-output .city" + oldvpn1city="$(eval $oldvpn1city)"; if echo $oldvpn1city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldvpn1city="Undetermined"; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: API call made to determine geolocation of VPN$vpn1slot: $oldvpn1ip ($oldvpn1city)" >> $LOGFILE + fi + + vpn1ip=$oldvpn1ip + vpn1city=$oldvpn1city + vpn1on="True" + + else + vpn1on="False" + fi + + #Check to see if there's a secondary VPN connection + vpn2slot=2 + VPN2State="$(_VPN_GetClientState_ ${vpn2slot})" + if [ -z "$VPN2State" ]; then VPN2State=0; fi # to catch possible wireguard interference + if [ "$VPN2State" -eq 2 ]; then + if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing VPN2 Stats...]"; fi + TUN2="tun1"$vpn2slot + NVRAMVPN2ADDR=$($timeoutcmd$timeoutsec nvram get vpn_client"$vpn2slot"_addr) + NVRAMVPN2IP=$(ping -c 1 -w 1 $NVRAMVPN2ADDR | awk -F '[()]' '/PING/ { print $2}') + + if [ "$NVRAMVPN2ADDR" != "$oldvpn2ADDR" ]; then + oldvpn2ip=$(curl --silent --fail --interface $TUN2 --request GET --url https://ipv4.icanhazip.com) + if [ -z $oldvpn2ip ]; then oldvpn2ip=$NVRAMVPN2IP; fi + oldvpn2ADDR=$NVRAMVPN2ADDR + fi + + if [ "$(echo $NVRAMVPN2IP | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then + oldvpn2ip=$NVRAMVPN2IP + oldvpn2city="Private Network" + elif [ "$vpn2ip" != "$oldvpn2ip" ]; then + oldvpn2city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldvpn2ip | jq --raw-output .city" + oldvpn2city="$(eval $oldvpn2city)"; if echo $oldvpn2city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldvpn2city="Undetermined"; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: API call made to determine geolocation of VPN$vpn2slot: $oldvpn2ip ($oldvpn2city)" >> $LOGFILE + fi + + vpn2ip=$oldvpn2ip + vpn2city=$oldvpn2city + vpn2on="True" + + else + vpn5on="False" + fi + + #Check to see if there's a third VPN connection + vpn3slot=3 + VPN3State="$(_VPN_GetClientState_ ${vpn3slot})" + if [ -z "$VPN3State" ]; then VPN3State=0; fi # to catch possible wireguard interference + if [ "$VPN3State" -eq 2 ]; then + if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing VPN3 Stats...]"; fi + TUN3="tun1"$vpn3slot + NVRAMVPN3ADDR=$($timeoutcmd$timeoutsec nvram get vpn_client"$vpn3slot"_addr) + NVRAMVPN3IP=$(ping -c 1 -w 1 $NVRAMVPN3ADDR | awk -F '[()]' '/PING/ { print $2}') + + if [ "$NVRAMVPN3ADDR" != "$oldvpn3ADDR" ]; then + oldvpn3ip=$(curl --silent --fail --interface $TUN3 --request GET --url https://ipv4.icanhazip.com) + if [ -z $oldvpn3ip ]; then oldvpn3ip=$NVRAMVPN3IP; fi + oldvpn3ADDR=$NVRAMVPN3ADDR + fi + + if [ "$(echo $NVRAMVPN3IP | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then + oldvpn3ip=$NVRAMVPN3IP + oldvpn3city="Private Network" + elif [ "$vpn3ip" != "$oldvpn3ip" ]; then + oldvpn3city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldvpn3ip | jq --raw-output .city" + oldvpn3city="$(eval $oldvpn3city)"; if echo $oldvpn3city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldvpn3city="Undetermined"; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: API call made to determine geolocation of VPN$vpn3slot: $oldvpn3ip ($oldvpn3city)" >> $LOGFILE + fi + + vpn3ip=$oldvpn3ip + vpn3city=$oldvpn3city + vpn3on="True" + + else + vpn3on="False" + fi + + #Check to see if there's a fourth VPN connection + vpn4slot=4 + VPN4State="$(_VPN_GetClientState_ ${vpn4slot})" + if [ -z "$VPN4State" ]; then VPN4State=0; fi # to catch possible wireguard interference + if [ "$VPN4State" -eq 2 ]; then + if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing VPN4 Stats...]"; fi + TUN4="tun1"$vpn4slot + NVRAMVPN4ADDR=$($timeoutcmd$timeoutsec nvram get vpn_client"$vpn4slot"_addr) + NVRAMVPN4IP=$(ping -c 1 -w 1 $NVRAMVPN4ADDR | awk -F '[()]' '/PING/ { print $2}') + + if [ "$NVRAMVPN4ADDR" != "$oldvpn4ADDR" ]; then + oldvpn4ip=$(curl --silent --fail --interface $TUN4 --request GET --url https://ipv4.icanhazip.com) + if [ -z $oldvpn4ip ]; then oldvpn4ip=$NVRAMVPN4IP; fi + oldvpn4ADDR=$NVRAMVPN4ADDR + fi + + if [ "$(echo $NVRAMVPN4IP | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then + oldvpn4ip=$NVRAMVPN4IP + oldvpn4city="Private Network" + elif [ "$vpn4ip" != "$oldvpn4ip" ]; then + oldvpn4city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldvpn4ip | jq --raw-output .city" + oldvpn4city="$(eval $oldvpn4city)"; if echo $oldvpn4city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldvpn4city="Undetermined"; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: API call made to determine geolocation of VPN$vpn4slot: $oldvpn4ip ($oldvpn4city)" >> $LOGFILE + fi + + vpn4ip=$oldvpn4ip + vpn4city=$oldvpn4city + vpn4on="True" + + else + vpn4on="False" + fi + + #Check to see if there's a fifth VPN connection + vpn5slot=5 + VPN5State="$(_VPN_GetClientState_ ${vpn5slot})" + if [ -z "$VPN5State" ]; then VPN5State=0; fi # to catch possible wireguard interference + if [ "$VPN5State" -eq 2 ]; then + if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing VPN5 Stats...]"; fi + TUN5="tun1"$vpn5slot + NVRAMVPN5ADDR=$($timeoutcmd$timeoutsec nvram get vpn_client"$vpn5slot"_addr) + NVRAMVPN5IP=$(ping -c 1 -w 1 $NVRAMVPN5ADDR | awk -F '[()]' '/PING/ { print $2}') + + if [ "$NVRAMVPN5ADDR" != "$oldvpn5ADDR" ]; then + oldvpn5ip=$(curl --silent --fail --interface $TUN5 --request GET --url https://ipv4.icanhazip.com) + if [ -z $oldvpn5ip ]; then oldvpn5ip=$NVRAMVPN5IP; fi + oldvpn5ADDR=$NVRAMVPN5ADDR + fi + + if [ "$(echo $NVRAMVPN5IP | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then + oldvpn5ip=$NVRAMVPN5IP + oldvpn5city="Private Network" + elif [ "$vpn5ip" != "$oldvpn5ip" ]; then + oldvpn5city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldvpn5ip | jq --raw-output .city" + oldvpn5city="$(eval $oldvpn5city)"; if echo $oldvpn5city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldvpn5city="Undetermined"; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: API call made to determine geolocation of VPN$vpn5slot: $oldvpn5ip ($oldvpn5city)" >> $LOGFILE + fi + + vpn5ip=$oldvpn5ip + vpn5city=$oldvpn5city + vpn5on="True" + + else + vpn5on="False" + fi + + #Check to see if there's a WGC1 connection + wg1slot=1 + WG1State="$(_WG_GetClientState_ ${wg1slot})" + if [ -z "$WG1State" ]; then WG1State=0; fi + if [ "$WG1State" -eq 2 ]; then + WGTUN1="wgc$wg1slot" + WGTUN1_IP=$($timeoutcmd$timeoutsec nvram get "$WGTUN1"_addr | cut -d '/' -f1) + WG1ADDR=$($timeoutcmd$timeoutsec nvram get "$WGTUN1"_ep_addr) + NVRAMWG1IP=$(ping -c 1 -w 1 $WGTUN1_IP | awk -F '[()]' '/PING/ { print $2}') + if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing WG1 Stats...]"; fi + if [ "$WG1ADDR" != "$oldwg1ADDR" ] || [ "$wg1ip" = "0.0.0.0" ]; then + # Added based on suggestion from @ZebMcKayhan + ip rule add from $WGTUN1_IP lookup $WGTUN1 prio 10 >/dev/null 2>&1 + oldwg1ip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN1" --request GET --url https://ipv4.icanhazip.com" + oldwg1ip="$(eval $oldwg1ip)" + if [ -z "$oldwg1ip" ] || echo "$oldwg1ip" | grep -qoE 'Internet|traffic|Error|error' + then + oldwg1ip="$NVRAMWG1IP" + fi + oldwg1ADDR=$WG1ADDR + # Added based on suggestion from @ZebMcKayhan + ip rule del prio 10 >/dev/null 2>&1 + fi + + if [ "$(echo "$oldwg1ip" | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then + oldwg1ip="$NVRAMWG1IP" + oldwg1city="Private Network" + elif [ "$wg1ip" != "$oldwg1ip" ]; then + oldwg1city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldwg1ip | jq --raw-output .city" + oldwg1city="$(eval $oldwg1city)"; if echo $oldwg1city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldwg1city="Undetermined"; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - API call made to determine geolocation of WG$wg1slot: $oldwg1ip ($oldwg1city)" >> $LOGFILE + fi + + wg1ip="$oldwg1ip" + wg1city="$oldwg1city" + wg1on="True" + + else + wg1on="False" + fi + + #Check to see if there's a WGC2 connection + wg2slot=2 + WG2State="$(_WG_GetClientState_ ${wg2slot})" + if [ -z "$WG2State" ]; then WG2State=0; fi + if [ "$WG2State" -eq 2 ]; then + WGTUN2="wgc$wg2slot" + WGTUN2_IP=$($timeoutcmd$timeoutsec nvram get "$WGTUN2"_addr | cut -d '/' -f1) + WG2ADDR=$($timeoutcmd$timeoutsec nvram get "$WGTUN2"_ep_addr) + NVRAMWG2IP=$(ping -c 1 -w 1 $WGTUN2_IP | awk -F '[()]' '/PING/ { print $2}') + if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing WG2 Stats...]"; fi + if [ "$WG2ADDR" != "$oldwg2ADDR" ] || [ "$wg2ip" = "0.0.0.0" ]; then + # Added based on suggestion from @ZebMcKayhan + ip rule add from $WGTUN2_IP lookup $WGTUN2 prio 10 >/dev/null 2>&1 + oldwg2ip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN2" --request GET --url https://ipv4.icanhazip.com" + oldwg2ip="$(eval $oldwg2ip)" + if [ -z "$oldwg2ip" ] || echo "$oldwg2ip" | grep -qoE 'Internet|traffic|Error|error' + then + oldwg2ip="$NVRAMWG2IP" + fi + oldwg2ADDR=$WG2ADDR + # Added based on suggestion from @ZebMcKayhan + ip rule del prio 10 >/dev/null 2>&1 + fi + + if [ "$(echo "$oldwg2ip" | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then + oldwg2ip="$NVRAMWG2IP" + oldwg2city="Private Network" + elif [ "$wg2ip" != "$oldwg2ip" ]; then + oldwg2city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldwg2ip | jq --raw-output .city" + oldwg2city="$(eval $oldwg2city)"; if echo $oldwg2city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldwg2city="Undetermined"; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - API call made to determine geolocation of WG$wg2slot: $oldwg2ip ($oldwg2city)" >> $LOGFILE + fi + + wg2ip="$oldwg2ip" + wg2city="$oldwg2city" + wg2on="True" + + else + wg2on="False" + fi + + #Check to see if there's a WGC3 connection + wg3slot=3 + WG3State="$(_WG_GetClientState_ ${wg3slot})" + if [ -z "$WG3State" ]; then WG3State=0; fi + if [ "$WG3State" -eq 2 ]; then + WGTUN3="wgc$wg3slot" + WGTUN3_IP=$($timeoutcmd$timeoutsec nvram get "$WGTUN3"_addr | cut -d '/' -f1) + WG3ADDR=$($timeoutcmd$timeoutsec nvram get "$WGTUN3"_ep_addr) + NVRAMWG3IP=$(ping -c 1 -w 1 $WGTUN3_IP | awk -F '[()]' '/PING/ { print $2}') + if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing WG3 Stats...]"; fi + if [ "$WG3ADDR" != "$oldwg3ADDR" ] || [ "$wg3ip" = "0.0.0.0" ]; then + # Added based on suggestion from @ZebMcKayhan + ip rule add from $WGTUN3_IP lookup $WGTUN3 prio 10 >/dev/null 2>&1 + oldwg3ip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN3" --request GET --url https://ipv4.icanhazip.com" + oldwg3ip="$(eval $oldwg3ip)" + if [ -z "$oldwg3ip" ] || echo "$oldwg3ip" | grep -qoE 'Internet|traffic|Error|error' + then + oldwg3ip="$NVRAMWG3IP" + fi + oldwg3ADDR=$WG3ADDR + # Added based on suggestion from @ZebMcKayhan + ip rule del prio 10 >/dev/null 2>&1 + fi + + if [ "$(echo "$oldwg3ip" | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then + oldwg3ip="$NVRAMWG3IP" + oldwg3city="Private Network" + elif [ "$wg3ip" != "$oldwg3ip" ]; then + oldwg3city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldwg3ip | jq --raw-output .city" + oldwg3city="$(eval $oldwg3city)"; if echo $oldwg3city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldwg3city="Undetermined"; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - API call made to determine geolocation of WG$wg3slot: $oldwg3ip ($oldwg3city)" >> $LOGFILE + fi + + wg3ip="$oldwg3ip" + wg3city="$oldwg3city" + wg3on="True" + + else + wg3on="False" + fi + + #Check to see if there's a WGC4 connection + wg4slot=4 + WG14State="$(_WG_GetClientState_ ${wg4slot})" + if [ -z "$WG4State" ]; then WG4State=0; fi + if [ "$WG4State" -eq 2 ]; then + WGTUN4="wgc$wg4slot" + WGTUN4_IP=$($timeoutcmd$timeoutsec nvram get "$WGTUN4"_addr | cut -d '/' -f1) + WG4ADDR=$($timeoutcmd$timeoutsec nvram get "$WGTUN4"_ep_addr) + NVRAMWG4IP=$(ping -c 1 -w 1 $WGTUN4_IP | awk -F '[()]' '/PING/ { print $2}') + if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing WG4 Stats...]"; fi + if [ "$WG4ADDR" != "$oldwg4ADDR" ] || [ "$wg4ip" = "0.0.0.0" ]; then + # Added based on suggestion from @ZebMcKayhan + ip rule add from $WGTUN4_IP lookup $WGTUN4 prio 10 >/dev/null 2>&1 + oldwg4ip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN4" --request GET --url https://ipv4.icanhazip.com" + oldwg4ip="$(eval $oldwg4ip)" + if [ -z "$oldwg4ip" ] || echo "$oldwg4ip" | grep -qoE 'Internet|traffic|Error|error' + then + oldwg4ip="$NVRAMWG4IP" + fi + oldwg4ADDR=$WG4ADDR + # Added based on suggestion from @ZebMcKayhan + ip rule del prio 10 >/dev/null 2>&1 + fi + + if [ "$(echo "$oldwg4ip" | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then + oldwg4ip="$NVRAMWG4IP" + oldwg4city="Private Network" + elif [ "$wg4ip" != "$oldwg4ip" ]; then + oldwg4city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldwg4ip | jq --raw-output .city" + oldwg4city="$(eval $oldwg4city)"; if echo $oldwg1city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldwg4city="Undetermined"; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - API call made to determine geolocation of WG$wg4slot: $oldwg4ip ($oldwg4city)" >> $LOGFILE + fi + + wg4ip="$oldwg4ip" + wg4city="$oldwg4city" + wg4on="True" + + else + wg4on="False" + fi + + #Check to see if there's a WGC5 connection + wg5slot=5 + WG5State="$(_WG_GetClientState_ ${wg5slot})" + if [ -z "$WG5State" ]; then WG5State=0; fi + if [ "$WG5State" -eq 2 ]; then + WGTUN5="wgc$wg5slot" + WGTUN5_IP=$($timeoutcmd$timeoutsec nvram get "$WGTUN5"_addr | cut -d '/' -f1) + WG5ADDR=$($timeoutcmd$timeoutsec nvram get "$WGTUN5"_ep_addr) + NVRAMWG5IP=$(ping -c 1 -w 1 $WGTUN5_IP | awk -F '[()]' '/PING/ { print $2}') + if [ "$1" = "loop" ]; then printf "${CGreen}\r[Refreshing WG5 Stats...]"; fi + if [ "$WG5ADDR" != "$oldwg5ADDR" ] || [ "$wg5ip" = "0.0.0.0" ]; then + # Added based on suggestion from @ZebMcKayhan + ip rule add from $WGTUN5_IP lookup $WGTUN5 prio 10 >/dev/null 2>&1 + oldwg5ip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WGTUN5" --request GET --url https://ipv4.icanhazip.com" + oldwg5ip="$(eval $oldwg5ip)" + if [ -z "$oldwg5ip" ] || echo "$oldwg5ip" | grep -qoE 'Internet|traffic|Error|error' + then + oldwg5ip="$NVRAMWG5IP" + fi + oldwg5ADDR=$WG5ADDR + # Added based on suggestion from @ZebMcKayhan + ip rule del prio 10 >/dev/null 2>&1 + fi + + if [ "$(echo "$oldwg5ip" | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ]; then + oldwg5ip="$NVRAMWG5IP" + oldwg5city="Private Network" + elif [ "$wg5ip" != "$oldwg5ip" ]; then + oldwg5city="curl --silent --retry 3 --request GET --url http://ip-api.com/json/$oldwg5ip | jq --raw-output .city" + oldwg5city="$(eval $oldwg5city)"; if echo $oldwg5city | grep -qoE '\b(error.*:.*True.*|Undefined)\b'; then oldwg5city="Undetermined"; fi + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - API call made to determine geolocation of WG$wg5slot: $oldwg5ip ($oldwg5city)" >> $LOGFILE + fi + + wg5ip="$oldwg5ip" + wg5city="$oldwg5city" + wg5on="True" + + else + wg5on="False" + fi + +} + +# ------------------------------------------------------------------------------------------------------------------------- +# GetVPNWGStats is a function that calculates connection stats from all active VPN and WG connections + +GetVPNWGStats() +{ + + if [ "$vpn1on" == "True" ]; then + oldvpntxrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn1slot/status 2>/dev/null) + oldvpnrxbytes="$(echo $oldvpntxrxbytes | cut -d' ' -f1)" + oldvpntxbytes="$(echo $oldvpntxrxbytes | cut -d' ' -f2)" + if [ -z $oldvpnrxbytes ]; then oldvpnrxbytes=0; fi + if [ -z $oldvpntxbytes ]; then oldvpntxbytes=0; fi + + if [ $oldvpnrxbytes -le 0 ]; then + oldvpnrxbytes=0 + elif [ $oldvpntxbytes -le 0 ]; then + oldvpntxbytes=0 + fi + fi + + if [ "$vpn2on" == "True" ]; then + oldvpn2txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn2slot/status 2>/dev/null) + oldvpn2rxbytes="$(echo $oldvpn2txrxbytes | cut -d' ' -f1)" + oldvpn2txbytes="$(echo $oldvpn2txrxbytes | cut -d' ' -f2)" + if [ -z $oldvpn2rxbytes ]; then oldvpn2rxbytes=0; fi + if [ -z $oldvpn2txbytes ]; then oldvpn2txbytes=0; fi + + if [ $oldvpn2rxbytes -le 0 ]; then + oldvpn2rxbytes=0 + elif [ $oldvpn2txbytes -le 0 ]; then + oldvpn2txbytes=0 + fi + fi + + if [ "$vpn3on" == "True" ]; then + oldvpn3txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn3slot/status 2>/dev/null) + oldvpn3rxbytes="$(echo $oldvpn3txrxbytes | cut -d' ' -f1)" + oldvpn3txbytes="$(echo $oldvpn3txrxbytes | cut -d' ' -f2)" + if [ -z $oldvpn3rxbytes ]; then oldvpn3rxbytes=0; fi + if [ -z $oldvpn3txbytes ]; then oldvpn3txbytes=0; fi + + if [ $oldvpn3rxbytes -le 0 ]; then + oldvpn3rxbytes=0 + elif [ $oldvpn3txbytes -le 0 ]; then + oldvpn3txbytes=0 + fi + fi + + if [ "$vpn4on" == "True" ]; then + oldvpn4txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn4slot/status 2>/dev/null) + oldvpn4rxbytes="$(echo $oldvpn4txrxbytes | cut -d' ' -f1)" + oldvpn4txbytes="$(echo $oldvpn4txrxbytes | cut -d' ' -f2)" + if [ -z $oldvpn4rxbytes ]; then oldvpn4rxbytes=0; fi + if [ -z $oldvpn4txbytes ]; then oldvpn4txbytes=0; fi + + if [ $oldvpn4rxbytes -le 0 ]; then + oldvpn4rxbytes=0 + elif [ $oldvpn4txbytes -le 0 ]; then + oldvpn4txbytes=0 + fi + fi + + if [ "$vpn5on" == "True" ]; then + oldvpn5txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client$vpn5slot/status 2>/dev/null) + oldvpn5rxbytes="$(echo $oldvpn5txrxbytes | cut -d' ' -f1)" + oldvpn5txbytes="$(echo $oldvpn5txrxbytes | cut -d' ' -f2)" + if [ -z $oldvpn5rxbytes ]; then oldvpn5rxbytes=0; fi + if [ -z $oldvpn5txbytes ]; then oldvpn5txbytes=0; fi + + if [ $oldvpn5rxbytes -le 0 ]; then + oldvpn5rxbytes=0 + elif [ $oldvpn5txbytes -le 0 ]; then + oldvpn5txbytes=0 + fi + fi + + # Check the wireguard connections + if [ "$wg1on" == "True" ]; then + oldwg1txrxbytes=$(wg show wgc1 transfer) + oldwg1rxbytes="$(echo $oldwg1txrxbytes | cut -d' ' -f3)" + oldwg1txbytes="$(echo $oldwg1txrxbytes | cut -d' ' -f2)" + if [ -z $oldwg1rxbytes ] || [ $oldwg1rxbytes -le 0 ]; then oldwg1rxbytes=0; fi + if [ -z $oldwg1txbytes ] || [ $oldwg1txbytes -le 0 ]; then oldwg1txbytes=0; fi + fi + + if [ "$wg2on" == "True" ]; then + oldwg2txrxbytes=$(wg show wgc2 transfer) + oldwg2rxbytes="$(echo $oldwg2txrxbytes | cut -d' ' -f3)" + oldwg2txbytes="$(echo $oldwg2txrxbytes | cut -d' ' -f2)" + if [ -z $oldwg2rxbytes ] || [ $oldwg2rxbytes -le 0 ]; then oldwg2rxbytes=0; fi + if [ -z $oldwg2txbytes ] || [ $oldwg2txbytes -le 0 ]; then oldwg2txbytes=0; fi + fi + + if [ "$wg3on" == "True" ]; then + oldwg3txrxbytes=$(wg show wgc3 transfer) + oldwg3rxbytes="$(echo $oldwg3txrxbytes | cut -d' ' -f3)" + oldwg3txbytes="$(echo $oldwg3txrxbytes | cut -d' ' -f2)" + if [ -z $oldwg3rxbytes ] || [ $oldwg3rxbytes -le 0 ]; then oldwg3rxbytes=0; fi + if [ -z $oldwg3txbytes ] || [ $oldwg3txbytes -le 0 ]; then oldwg3txbytes=0; fi + fi + + if [ "$wg4on" == "True" ]; then + oldwg4txrxbytes=$(wg show wgc4 transfer) + oldwg4rxbytes="$(echo $oldwg4txrxbytes | cut -d' ' -f3)" + oldwg4txbytes="$(echo $oldwg4txrxbytes | cut -d' ' -f2)" + if [ -z $oldwg4rxbytes ] || [ $oldwg4rxbytes -le 0 ]; then oldwg4rxbytes=0; fi + if [ -z $oldwg4txbytes ] || [ $oldwg4txbytes -le 0 ]; then oldwg4txbytes=0; fi + fi + + if [ "$wg5on" == "True" ]; then + oldwg5txrxbytes=$(wg show wgc5 transfer) + oldwg5rxbytes="$(echo $oldwg5txrxbytes | cut -d' ' -f3)" + oldwg5txbytes="$(echo $oldwg5txrxbytes | cut -d' ' -f2)" + if [ -z $oldwg5rxbytes ] || [ $oldwg5rxbytes -le 0 ]; then oldwg5rxbytes=0; fi + if [ -z $oldwg5txbytes ] || [ $oldwg5txbytes -le 0 ]; then oldwg5txbytes=0; fi + fi + +} + +# ------------------------------------------------------------------------------------------------------------------------- +# VPN_GetClientState was created by @Martinski in many thanks to trying to eliminate unknown operand errors due to null +# vpn_clientX_state values + +_VPN_GetClientState_() +{ + if [ $# -lt 1 ] || [ -z "$1" ] || ! echo "$1" | grep -qE "^[1-5]$" + then echo "**ERROR**" ; return 1 ; fi + + local nvramVal="$($timeoutcmd$timeoutsec nvram get "vpn_client${1}_state")" + if [ -z "$nvramVal" ] || ! echo "$nvramVal" | grep -qE "^[0-9]$" + then echo "0" ; else echo "$nvramVal" ; fi + return 0 +} + +# ------------------------------------------------------------------------------------------------------------------------- +# WG_GetClientState is based off _VPN_GetClientState_ + +_WG_GetClientState_() +{ + if [ $# -lt 1 ] || [ -z "$1" ] || ! echo "$1" | grep -qE "^[1-5]$" + then echo "**ERROR**" ; return 1 ; fi + + # Inspiration from ZebMcKayHan's WGC Watchdog Script + last_handshake=$(wg show wgc$1 latest-handshakes | awk '{print $2}') >/dev/null 2>&1 + + if [ -z $last_handshake ] + then + WGnvramVal=0 #disconnected + else + WGnvramVal=2 #connected + fi + + #local WGnvramVal="$($timeoutcmd$timeoutsec nvram get "wgc${1}_enable")" + if [ -z "$WGnvramVal" ] || ! echo "$WGnvramVal" | grep -qE "^[+-]?[0-9]$" + then echo "0" ; else echo "$WGnvramVal" ; fi + return 0 +} + +##-------------------------------------## +## Added by Martinski W. [2024-Nov-02] ## +##-------------------------------------## +_SetUpTimeoutCmdVars_() +{ + # If the timeout utility is available then use it # + if [ -z "${timeoutcmd:+xSETx}" ] && [ -f "/opt/bin/timeout" ] + then + timeoutcmd="timeout " + timeoutsec="10" + timeoutlng="60" + fi +} + +##-------------------------------------## +## Added by Martinski W. [2024-Nov-02] ## +##-------------------------------------## +_SetLAN_HostName_() +{ + [ -z "${LAN_HostName:+xSETx}" ] && \ + LAN_HostName="$($timeoutcmd$timeoutsec nvram get lan_hostname)" +} + +_GetLAN_HostName_() +{ _SetLAN_HostName_ ; echo "$LAN_HostName" ; } + +trap '_IgnoreKeypresses_ OFF ; exit 0' EXIT INT QUIT ABRT TERM + +# ------------------------------------------------------------------------------------------------------------------------- +# Begin Commandline Argument Gatekeeper and Configuration Utility Functionality +# ------------------------------------------------------------------------------------------------------------------------- +##----------------------------------------## +## Modified by Martinski W. [2024-Nov-02] ## +##----------------------------------------## + +#DEBUG=; set -x # uncomment/comment to enable/disable debug mode +#{ # uncomment/comment to enable/disable debug mode + + _SetUpTimeoutCmdVars_ + _SetLAN_HostName_ + + # Create the necessary folder/file structure for RTRMON under /jffs/addons + if [ ! -d "/jffs/addons/rtrmon.d" ]; then + mkdir -p "/jffs/addons/rtrmon.d" + fi + + # Check for Updates + updatecheck + + RouterModel="$($timeoutcmd$timeoutsec nvram get odmpid)" + [ -z "$RouterModel" ] && RouterModel="$($timeoutcmd$timeoutsec nvram get productid)" + + FWVER="$($timeoutcmd$timeoutsec nvram get firmver | tr -d '.')" + BUILDNO="$($timeoutcmd$timeoutsec nvram get buildno)" + EXTENDNO="$($timeoutcmd$timeoutsec nvram get extendno)" + if [ -z "$EXTENDNO" ]; then EXTENDNO=0; fi + FWBUILD="${FWVER}.${BUILDNO}_${EXTENDNO}" + + # Check for advanced router Features + FourBandCustom55624="False" + FourBandCustom56624="False" + ThreeBand2456="False" + ThreeBand2455="False" + + if [ "$RouterModel" = "GT-AXE16000" ] || [ "$RouterModel" = "GT-BE98" ]; then + FourBandCustom55624="True" + fi + if [ "$RouterModel" = "GT-BE98_Pro" ]; then + FourBandCustom56624="True" + fi + if [ "$RouterModel" = "GT-AXE11000" ] || [ "$RouterModel" = "ZenWiFi_ET8" ] || [ "$RouterModel" = "RT-BE96U" ] || [ "$RouterModel" = "RT-BE92U" ]; then + ThreeBand2456="True" + fi + if [ "$RouterModel" = "GT-AX11000_Pro" ] || [ "$RouterModel" = "GT-AX11000" ] || [ "$RouterModel" = "ZenWiFi_Pro_XT12" ] || [ "$RouterModel" = "ZenWiFi_XT8" ]; then + ThreeBand2455="True" + fi + + # Check what mode the router is in: 1=Router, 2=AP, 3=iMesh Node # + OpsMode="$($timeoutcmd$timeoutsec nvram get sw_mode)" + #OpsMode=3 + + # Check and see if any commandline option is being used + if [ $# -eq 0 ] || [ -z "$1" ] + then + clear + echo "" + echo "RTRMON v$Version" + echo "" + echo "Exiting due to missing commandline options!" + echo "(run 'rtrmon.sh -h' for help)" + echo "" + echo -e "${CClear}" + exit 0 + fi + + # Check and see if an invalid commandline option is being used + if [ "$1" = "-h" ] || [ "$1" = "-help" ] || [ "$1" = "-config" ] || [ "$1" = "-setup" ] || \ + [ "$1" = "-monitor" ] || [ "$1" = "-reset" ] || [ "$1" = "-update" ] || \ + [ "$1" = "-screen" ] || [ "$1" = "-uninstall" ] || [ "$1" = "-log" ] || \ + { [ $# -gt 1 ] && [ "$2" = "-now" ] ; } || { [ $# -gt 2 ] &&[ "$3" = "-now" ] ; } + then + clear + else + clear + echo "" + echo "RTRMON v$Version" + echo "" + echo "Exiting due to invalid commandline options!" + echo "(run 'rtrmon.sh -h' for help)" + echo "" + echo -e "${CClear}" + exit 0 + fi + + # Check to see if the help option is being called + if [ "$1" == "-h" ] || [ "$1" == "-help" ] + then + clear + echo "" + echo "RTRMON v$Version Commandline Option Usage:" + echo "" + echo "rtrmon.sh -h | -help" + echo "rtrmon.sh -log" + echo "rtrmon.sh -config" + echo "rtrmon.sh -update" + echo "rtrmon.sh -setup" + echo "rtrmon.sh -uninstall" + echo "rtrmon.sh -screen" + echo "rtrmon.sh -monitor" + echo "rtrmon.sh -screen/-monitor X" + echo "rtrmon.sh -screen (X) -now" + echo "" + echo " -h | -help (this output)" + echo " -log (display the current log contents)" + echo " -config (configuration utility)" + echo " -update (script update utility)" + echo " -setup (setup/dependencies utility)" + echo " -uninstall (uninstall utility)" + echo " -screen (normal router monitoring using the screen utility)" + echo " -monitor (normal router monitoring operations)" + echo " -screen/-monitor X (X = display screen 1-6 upon execution)" + echo " -screen -now (bypass screen instructions and 5 sec timer)" + echo "" + echo " Examples:" + echo " rtrmon -screen -now (bypass screen timer directly into monitor mode)" + echo " rtrmon -screen 2 (jump to page 2 upon execution using screen)" + echo " rtrmon -screen 3 -now (bypass timer and jump to page 3 using screen)" + echo " rtrmon -monitor 4 (jump to page 4 in monitoring mode)" + echo "" + echo -e "${CClear}" + exit 0 + fi + + # Check to see if the log option is being called, and display through nano + if [ "$1" == "-log" ] + then + vlogs + exit 0 + fi + + # Check to see if the configuration option is being called, and run through setup utility + if [ "$1" == "-config" ] + then + vconfig + echo -e "${CClear}" + exit 0 + fi + + # Check to see if the update option is being called + if [ "$1" == "-update" ] + then + vupdate + echo -e "${CClear}" + exit 0 + fi + + # Check to see if the install option is being called + if [ "$1" = "-setup" ] + then + vsetup + exit 0 + fi + + # Check to see if the uninstall option is being called + if [ "$1" = "-uninstall" ] + then + vuninstall + echo -e "${CClear}" + exit 0 + fi + + # Check to see if the -now parameter is being called to bypass the screen timer + if [ $# -gt 1 ] && [ "$2" = "-now" ] + then + bypassScreenTimer=1 + elif [ $# -gt 2 ] && [ "$3" = "-now" ] + then + bypassScreenTimer2=1 + fi + + # Check to see if the screen option is being called and run operations normally using the screen utility + if [ "$1" = "-screen" ] + then + screen -wipe >/dev/null 2>&1 # Kill any dead screen sessions + sleep 1 + ScreenSess="$(screen -ls | grep "rtrmon" | awk '{print $1}' | cut -d . -f 1)" + if [ -z "$ScreenSess" ] + then + if [ "$bypassScreenTimer" = "1" ] + then + screen -dmS "rtrmon" $APPPATH -monitor + sleep 1 + screen -r rtrmon + elif [ "$bypassScreenTimer2" = "1" ] + then + if [ $# -lt 2 ] || [ -z "$2" ]; then + screen -dmS "rtrmon" $APPPATH -monitor + elif [ "$2" -ge 1 ] && [ "$2" -le 6 ]; then + screen -dmS "rtrmon" $APPPATH -monitor $2 + else + screen -dmS "rtrmon" $APPPATH -monitor + fi + sleep 1 + screen -r rtrmon + else + clear + echo -e "${CClear}Executing ${CGreen}RTRMON v$Version ${CClear}using the SCREEN utility...${CClear}" + echo "" + echo -e "${CClear}IMPORTANT:${CClear}" + echo -e "${CClear}In order to keep RTRMON running in the background,${CClear}" + echo -e "${CClear}properly exit the SCREEN session by using: ${CGreen}CTRL-A + D${CClear}" + echo "" + if [ $# -lt 2 ] || [ -z "$2" ]; then + screen -dmS "rtrmon" $APPPATH -monitor + elif [ "$2" -ge 1 ] && [ "$2" -le 6 ]; then + screen -dmS "rtrmon" $APPPATH -monitor $2 + else + screen -dmS "rtrmon" $APPPATH -monitor + fi + sleep 2 + echo -e "${CClear}Switching to the SCREEN session in T-5 sec...${CClear}" + echo -e "${CClear}" + spinner 5 + screen -r rtrmon + exit 0 + fi + else + if [ "$bypassScreenTimer" = "1" ]; then + sleep 1 + else + clear + echo -e "${CClear}Connecting to existing ${CGreen}RTRMON v$Version ${CClear}SCREEN session...${CClear}" + echo "" + echo -e "${CClear}IMPORTANT:${CClear}" + echo -e "${CClear}In order to keep RTRMON running in the background,${CClear}" + echo -e "${CClear}properly exit the SCREEN session by using: ${CGreen}CTRL-A + D${CClear}" + echo "" + echo -e "${CClear}Switching to the SCREEN session in T-5 sec...${CClear}" + echo -e "${CClear}" + spinner 5 + fi + fi + screen -dr $ScreenSess + exit 0 + fi + + # Check to see if the monitor option is being called and run operations normally + if [ "$1" = "-monitor" ] + then + clear + if [ -f "$CFGPATH" ] && [ -f "/opt/bin/column" ] && [ -f "/opt/bin/timeout" ] && [ -f "/opt/sbin/screen" ] && [ -f "/opt/bin/nmap" ] && [ -f "/opt/bin/jq" ] && [ -f "/opt/bin/iftop" ] + then + printf "\r\033[0K${InvYellow} ${CClear} Please wait..." ; _ConsumeKeypressBuffer_ + source "$CFGPATH" + + if [ -f /root/.config/ookla/speedtest-cli.json ] && \ + [ ! -f /jffs/addons/rtrmon.d/speedtest-cli.json ] + then + cp -fp /root/.config/ookla/speedtest-cli.json /jffs/addons/rtrmon.d/speedtest-cli.json 2>/dev/null + fi + + if [ ! -d "/root/.config/ookla" ] + then + mkdir -p "/root/.config/ookla" + [ -f /jffs/addons/rtrmon.d/speedtest-cli.json ] && \ + cp -fp /jffs/addons/rtrmon.d/speedtest-cli.json /root/.config/ookla/speedtest-cli.json 2>/dev/null + fi + + NextPage="$([ $# -gt 1 ] && echo "$2" | tr -d -c 1-7 || echo)" + if [ -z "$NextPage" ]; then NextPage=1 ; fi + + # Per @Stephen Harrington's suggestion, check NVRAM to see if WiFi is turned on, else mark them as disabled + if [ "$FourBandCustom55624" == "True" ]; then + if [ "$($timeoutcmd$timeoutsec nvram get wl0_radio)" -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + if [ "$($timeoutcmd$timeoutsec nvram get wl1_radio)" -eq 0 ]; then + MaxSpeed52GhzNow=0 + else + MaxSpeed52GhzNow=$MaxSpeed5Ghz + fi + if [ "$($timeoutcmd$timeoutsec nvram get wl2_radio)" -eq 0 ]; then + MaxSpeed6GhzNow=0 + else + MaxSpeed6GhzNow=$MaxSpeed6Ghz + fi + if [ "$($timeoutcmd$timeoutsec nvram get wl3_radio)" -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + elif [ "$FourBandCustom56624" == "True" ]; then + if [ "$($timeoutcmd$timeoutsec nvram get wl0_radio)" -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + if [ "$($timeoutcmd$timeoutsec nvram get wl1_radio)" -eq 0 ]; then + MaxSpeed6GhzNow=0 + else + MaxSpeed6GhzNow=$MaxSpeed6Ghz + fi + if [ "$($timeoutcmd$timeoutsec nvram get wl2_radio)" -eq 0 ]; then + MaxSpeed62GhzNow=0 + else + MaxSpeed62GhzNow=$MaxSpeed6Ghz + fi + if [ "$($timeoutcmd$timeoutsec nvram get wl3_radio)" -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + elif [ "$ThreeBand2456" == "True" ]; then + if [ "$($timeoutcmd$timeoutsec nvram get wl0_radio)" -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + if [ "$($timeoutcmd$timeoutsec nvram get wl1_radio)" -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + if [ "$($timeoutcmd$timeoutsec nvram get wl2_radio)" -eq 0 ]; then + MaxSpeed6GhzNow=0 + else + MaxSpeed6GhzNow=$MaxSpeed6Ghz + fi + elif [ "$ThreeBand2455" == "True" ]; then + if [ "$($timeoutcmd$timeoutsec nvram get wl0_radio)" -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + if [ "$($timeoutcmd$timeoutsec nvram get wl1_radio)" -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + if [ "$($timeoutcmd$timeoutsec nvram get wl2_radio)" -eq 0 ]; then + MaxSpeed52GhzNow=0 + else + MaxSpeed52GhzNow=$MaxSpeed5Ghz + fi + else + if [ "$($timeoutcmd$timeoutsec nvram get wl0_radio)" -eq 0 ]; then + MaxSpeed24GhzNow=0 + else + MaxSpeed24GhzNow=$MaxSpeed24Ghz + fi + if [ "$($timeoutcmd$timeoutsec nvram get wl1_radio)" -eq 0 ]; then + MaxSpeed5GhzNow=0 + else + MaxSpeed5GhzNow=$MaxSpeed5Ghz + fi + fi + + else + echo -e "${CRed}Error: RTRMON is not configured or does not have all the required dependencies${CClear}" + echo -e "${CRed}installed. Launching 'rtrmon -setup' to install dependencies/complete setup!${CClear}" + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - ERROR: RTRMON is not configured/missing dependencies. Please run the setup tool." >> $LOGFILE + echo "" + echo -e "${CGreen}Launching the Setup Menu in T-5 sec...${CClear}" + spinner 5 + vsetup + echo -e "${CClear}" + exit 0 + fi + fi + +##----------------------------------------## +## Modified by Martinski W. [2024-Nov-03] ## +##----------------------------------------## +# ------------------------------------------------------------------------------------------------------------------------- +# Main RTRMON program initialization +# ------------------------------------------------------------------------------------------------------------------------- + _IgnoreKeypresses_ ON + # Display the logo and indicator that stats are being gathered. + + clear + logoNM + echo -e "\r${CGreen} [Initiating Boot Sequence - Gathering Initial Stats...]" + echo "" + INITIALBOOT=1 + trimlogs + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: RTRMON is initializing for the first time..." >> $LOGFILE + + # Capture initial traffic and store current WAN/WiFi bytes stats + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + if [ $WANOverride == "Auto" ]; then WANIFNAME=$(get_wan_setting ifname); else WANIFNAME=$WANOverride; fi + if [ -z $WANIFNAME ]; then WANIFNAME="eth0"; fi + oldwanrxbytes="$(cat /sys/class/net/$WANIFNAME/statistics/rx_bytes)" + oldwantxbytes="$(cat /sys/class/net/$WANIFNAME/statistics/tx_bytes)" + fi + + if [ "$FourBandCustom55624" == "True" ]; then + ifname5=$($timeoutcmd$timeoutsec nvram get wl0_ifname) + ifname52=$($timeoutcmd$timeoutsec nvram get wl1_ifname) + ifname6=$($timeoutcmd$timeoutsec nvram get wl2_ifname) + ifname24=$($timeoutcmd$timeoutsec nvram get wl3_ifname) + elif [ "$FourBandCustom56624" == "True" ]; then + ifname5=$($timeoutcmd$timeoutsec nvram get wl0_ifname) + ifname6=$($timeoutcmd$timeoutsec nvram get wl1_ifname) + ifname62=$($timeoutcmd$timeoutsec nvram get wl2_ifname) + ifname24=$($timeoutcmd$timeoutsec nvram get wl3_ifname) + elif [ "$ThreeBand2456" == "True" ]; then + ifname24=$($timeoutcmd$timeoutsec nvram get wl0_ifname) + ifname5=$($timeoutcmd$timeoutsec nvram get wl1_ifname) + ifname6=$($timeoutcmd$timeoutsec nvram get wl2_ifname) + elif [ "$ThreeBand2455" == "True" ]; then + ifname24=$($timeoutcmd$timeoutsec nvram get wl0_ifname) + ifname5=$($timeoutcmd$timeoutsec nvram get wl1_ifname) + ifname52=$($timeoutcmd$timeoutsec nvram get wl2_ifname) + else + ifname24=$($timeoutcmd$timeoutsec nvram get wl0_ifname) + ifname5=$($timeoutcmd$timeoutsec nvram get wl1_ifname) + fi + + old24rxbytes="$(cat /sys/class/net/$ifname24/statistics/rx_bytes)" + old24txbytes="$(cat /sys/class/net/$ifname24/statistics/tx_bytes)" + old5rxbytes="$(cat /sys/class/net/$ifname5/statistics/rx_bytes)" + old5txbytes="$(cat /sys/class/net/$ifname5/statistics/tx_bytes)" + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then + old52rxbytes="$(cat /sys/class/net/$ifname52/statistics/rx_bytes)" + old52txbytes="$(cat /sys/class/net/$ifname52/statistics/tx_bytes)" + fi + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then + old6rxbytes="$(cat /sys/class/net/$ifname6/statistics/rx_bytes)" + old6txbytes="$(cat /sys/class/net/$ifname6/statistics/tx_bytes)" + fi + if [ "$FourBandCustom56624" == "True" ]; then + old62rxbytes="$(cat /sys/class/net/$ifname62/statistics/rx_bytes)" + old62txbytes="$(cat /sys/class/net/$ifname62/statistics/tx_bytes)" + fi + oldlanrxbytes="$(cat /sys/class/net/br0/statistics/rx_bytes)" + oldlantxbytes="$(cat /sys/class/net/br0/statistics/tx_bytes)" + + #Get the Initial VPN stats + GetVPNWGIPCITY + GetVPNWGStats + + # Get initial TOP stats to average across the interval period + RM_ELAPSED_TIME=0 + RM_START_TIME="$(date +%s)" + + ##----------------------------------------## + ## Modified by Martinski W. [2024-Nov-04] ## + ##----------------------------------------## + timer=0 + lastTimerSec=0 + updateTimer=true + savedInterval="$Interval" + Interval="$bootInterval" + + # Initial Boot Sequence Loop # + while [ "$timer" -lt "$Interval" ] + do + if "$updateTimer" + then + updateTimer=false + timer="$((timer+1))" + lastTimerSec="$(date +%s)" + gettopstats "$timer" + fi + preparebar 53 "|" + progressbaroverride "$timer" "$Interval" "" "s" "Standard" + + ## Prevent repeatedly fast key presses from updating the timer ## + [ "$(date +%s)" -gt "$lastTimerSec" ] && updateTimer=true + done + + calculatestats + oldstats + + clear + INITIALBOOT=0 + Interval="$savedInterval" + +# ------------------------------------------------------------------------------------------------------------------------- +# Main loop that calls functions to perform all necessary calculations across the interval period +# ------------------------------------------------------------------------------------------------------------------------- +##----------------------------------------## +## Modified by Martinski W. [2024-Nov-03] ## +##----------------------------------------## +while true +do + + _SetUpTimeoutCmdVars_ + _SetLAN_HostName_ + _IgnoreKeypresses_ ON + + if [ "$NextPage" = "1" ]; then + DisplayPage1 + echo "" + elif [ "$NextPage" = "2" ]; then + DisplayPage2 + echo "" + elif [ "$NextPage" = "3" ]; then + DisplayPage3 + echo "" + elif [ "$NextPage" = "4" ]; then + DisplayPage4 + echo "" + elif [ "$NextPage" = "5" ]; then + DisplayPage5 + #echo "" + elif [ "$NextPage" = "6" ]; then + DisplayPage6 + #echo "" + elif [ "$NextPage" = "7" ]; then + DisplayPage7 + fi + + # Reset stats after the UI has finished drawing + memused1=0 + memfree1=0 + memshrd1=0 + membuff1=0 + memcach1=0 + memused2=0 + memfree2=0 + memshrd2=0 + membuff2=0 + memcach2=0 + cpuusr1=0 + cpusys1=0 + cpunice1=0 + cpuidle1=0 + displaycpuusr1=0 + displaycpusys1=0 + displaycpunice1=0 + displaycpuidle1=0 + displaycpuirq1=0 + + # Get fresh WAN stats + if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then + oldwanrxbytes="$(cat /sys/class/net/$WANIFNAME/statistics/rx_bytes)" + oldwantxbytes="$(cat /sys/class/net/$WANIFNAME/statistics/tx_bytes)" + fi + old24rxbytes="$(cat /sys/class/net/$ifname24/statistics/rx_bytes)" + old24txbytes="$(cat /sys/class/net/$ifname24/statistics/tx_bytes)" + old5rxbytes="$(cat /sys/class/net/$ifname5/statistics/rx_bytes)" + old5txbytes="$(cat /sys/class/net/$ifname5/statistics/tx_bytes)" + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then + old52rxbytes="$(cat /sys/class/net/$ifname52/statistics/rx_bytes)" + old52txbytes="$(cat /sys/class/net/$ifname52/statistics/tx_bytes)" + fi + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then + old6rxbytes="$(cat /sys/class/net/$ifname6/statistics/rx_bytes)" + old6txbytes="$(cat /sys/class/net/$ifname6/statistics/tx_bytes)" + fi + if [ "$FourBandCustom56624" == "True" ]; then + old62rxbytes="$(cat /sys/class/net/$ifname62/statistics/rx_bytes)" + old62txbytes="$(cat /sys/class/net/$ifname62/statistics/tx_bytes)" + fi + oldlanrxbytes="$(cat /sys/class/net/br0/statistics/rx_bytes)" + oldlantxbytes="$(cat /sys/class/net/br0/statistics/tx_bytes)" + + # Get fresh VPN stats + echo "" + GetVPNWGIPCITY loop + GetVPNWGStats + + printf "${CGreen}\r " + printf "${CGreen}\r" + + + # Run through the stats gathering loop based on the current interval + RM_ELAPSED_TIME=0 + RM_START_TIME="$(date +%s)" + + ##----------------------------------------## + ## Modified by Martinski W. [2024-Nov-05] ## + ##----------------------------------------## + timer=0 + lastTimerSec=0 + updateTimer=true + pausedTimerEnabled=false + pausedTimerDispStr="" + + # Main Loop # + while [ "$timer" -lt "$Interval" ] + do + if "$updateTimer" + then + updateTimer=false + timer="$((timer+1))" + lastTimerSec="$(date +%s)" + gettopstats "$timer" + fi + preparebar 46 "|" + progressbaroverride "$timer" "$Interval" "" "s" "Standard" + if [ "$timerReset" = "1" ] ; then timer="$Interval" ; fi + + ## Prevent repeatedly fast key presses from updating the timer ## + [ "$(date +%s)" -gt "$lastTimerSec" ] && updateTimer=true + done + + # Do a fresh round of stats and save them to the old stats for display purposes + calculatestats + oldstats + clear + + if [ "$autorotate" = "1" ] && [ "$timer" -ge "$Interval" ] + then + if [ "$NextPage" = "1" ]; then NextPage=2 #DisplayPage2# + elif [ "$NextPage" = "2" ]; then NextPage=3 #DisplayPage3# + elif [ "$NextPage" = "3" ]; then NextPage=4 #DisplayPage4# + elif [ "$NextPage" = "4" ]; then NextPage=5 #DisplayPage5# + elif [ "$NextPage" = "5" ]; then NextPage=6 #DisplayPage6# + elif [ "$NextPage" = "6" ]; then NextPage=7 #DisplayPage7# + elif [ "$NextPage" = "7" ]; then NextPage=1 #DisplayPage1# + fi + fi + + prevHideOpts=X + prevSortByOpt=X +done + +_IgnoreKeypresses_ OFF + +exit 0 + +#} #2>&1 | tee $LOG | logger -t $(basename $0)[$$] # uncomment/comment to enable/disable debug mode From 299bf291f3e94450977096d602f198fd05a6488e Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Thu, 4 Dec 2025 21:59:01 -0500 Subject: [PATCH 08/62] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fd515be..4a0fbcb 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# RTRMON v2.2.3 +# RTRMON v2.2.4 Asus-Merlin Router Monitor by Viktor Jaep, 2022-2025 -Updated on 2025-Nov-16 +Updated on 2025-Dec-04 --- From 530ec62d648bf734b8bb205b62615a573352e215 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Thu, 4 Dec 2025 22:00:05 -0500 Subject: [PATCH 09/62] Update enhancements.txt --- enhancements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/enhancements.txt b/enhancements.txt index 505b78c..21da1e1 100644 --- a/enhancements.txt +++ b/enhancements.txt @@ -2,11 +2,11 @@ Future Enhancements (Possible/Planned) ----------------------------- * AMTM Email notifications on certain events (like 80% disk usage) * Perhaps check the amount of uptime of the router, and if it's less than 5 minutes, send a notification that the router just rebooted -* WAN down functionality to put RTRMON in standby if the WAN isn't working? -* Display issues w/ standard WiFi ranges when using complex VLAN setup/iMesh @visortgw +* WAN down functionality to put RTRMON in standby if the WAN isn't working, or at least show interface down. Completed: ---------- +* Display issues w/ standard WiFi ranges when using complex VLAN setup/iMesh @visortgw * Fix VPN/WG Speedtest availability in UI if one or the other isn't being used * Include Wireguard Slots + Stats * opkg install column -- RTRMON! From 7d69151e1bc748ac2769488a1f41dbae4eb10094 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Thu, 4 Dec 2025 22:07:29 -0500 Subject: [PATCH 10/62] Update changelog.txt --- changelog.txt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/changelog.txt b/changelog.txt index 014a9c8..9fe8b36 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,18 @@ +v2.2.4 - (TBA) + - PATCH: HUGE HUGE THANKS to both @ExtremeFiretop and @visortgw for their help getting the + wired/wireless client page (#7) working again. Apparently something had broken between a + firmware release that seemed to be causing some incorrect reporting on this page. Both these + guys stepped in, and were able to collaboratively bring this home, and get this page to + report things accurately again. RTRMON wouldn't be as awesome as it is without these two + incredible gentlemen! :) Thank you! + - PATCH: Thanks to a CPU temperature issue report from @fr0s7, it was found that the normal + methods of finding CPU temp readings were no longer working on the RT-BE92U. @Dave14503 came + to the rescue, and was able to find the correct file for a temp reading. Thank you both! + - PATCH: Some oversight on my part... after my efforts to optimize my code, I inadvertently + left out an optimization that affects vpn/wg connections that are using private IPs, and was + causing a 1min delay when RTRMON started up. I got this added back in, and is launching + successfully again. Thanks to @visortgw for the report! + v2.2.3 - (November 16, 2025) - PATCH: Modified how the memory stats are being captured, and is now more in line with the results shown in the Web UI. Stats are now coming from /proc/meminfo. From 9433a25b4bed8d99fc492ba698efdd0ccd740e61 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Fri, 5 Dec 2025 22:31:39 -0500 Subject: [PATCH 11/62] Update changelog.txt --- changelog.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/changelog.txt b/changelog.txt index 9fe8b36..9e45681 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,9 +1,9 @@ -v2.2.4 - (TBA) +v2.2.4b - (TBA) - PATCH: HUGE HUGE THANKS to both @ExtremeFiretop and @visortgw for their help getting the wired/wireless client page (#7) working again. Apparently something had broken between a firmware release that seemed to be causing some incorrect reporting on this page. Both these - guys stepped in, and were able to collaboratively bring this home, and get this page to - report things accurately again. RTRMON wouldn't be as awesome as it is without these two + guys stepped in, and were able to collaboratively knock it out of the park, and get this page + to report things accurately again. RTRMON wouldn't be as awesome as it is without these two incredible gentlemen! :) Thank you! - PATCH: Thanks to a CPU temperature issue report from @fr0s7, it was found that the normal methods of finding CPU temp readings were no longer working on the RT-BE92U. @Dave14503 came @@ -12,6 +12,8 @@ v2.2.4 - (TBA) left out an optimization that affects vpn/wg connections that are using private IPs, and was causing a 1min delay when RTRMON started up. I got this added back in, and is launching successfully again. Thanks to @visortgw for the report! + - PATCH: Various spacing tweaks to ensure alignment of required data elements. That's right. + I blame the OCD. v2.2.3 - (November 16, 2025) - PATCH: Modified how the memory stats are being captured, and is now more in line with the From bb0e084ba0d264cc3332c99384218ffa06e68dc5 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Fri, 5 Dec 2025 22:33:01 -0500 Subject: [PATCH 12/62] Update rtrmon.sh --- rtrmon.sh | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/rtrmon.sh b/rtrmon.sh index 166c275..5580f69 100644 --- a/rtrmon.sh +++ b/rtrmon.sh @@ -15,7 +15,7 @@ # # Please use the 'sh rtrmon.sh -setup' command to configure the necessary parameters that match your environment the best! # -# Last Modified: 2025-Dec-4 +# Last Modified: 2025-Dec-5 ########################################################################################################################### #Preferred standard router binaries path @@ -24,8 +24,8 @@ export PATH="/sbin:/bin:/usr/sbin:/usr/bin:$PATH" # ------------------------------------------------------------------------------------------------------------------------- # System Variables (Do not change beyond this point or this may change the programs ability to function correctly) # ------------------------------------------------------------------------------------------------------------------------- -Version="2.2.4" -Beta=0 +Version="2.2.4b1" +Beta=1 ScreenshotMode=0 LOGFILE="/jffs/addons/rtrmon.d/rtrmon.log" # Logfile path/name that captures important date/time events - change APPPATH="/jffs/scripts/rtrmon.sh" # Path to the location of rtrmon.sh @@ -4802,12 +4802,12 @@ DisplayPage7() section_output="$(attachedwificlients "$ifname24")" if [ -n "$section_output" ] && \ ! echo "$section_output" | grep -q "No Devices Connected"; then - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 2.4GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname24 ${CClear}" + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 2.4GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname24 ${CClear}" printf '%s\n' "$section_output" echo "" fi else - echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 2.4GHz ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" + echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 2.4GHz ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" echo "" fi @@ -4819,12 +4819,12 @@ DisplayPage7() section_output="$(attachedwificlients "$ifname5")" if [ -n "$section_output" ] && \ ! echo "$section_output" | grep -q "No Devices Connected"; then - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname5 ${CClear}" + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname5 ${CClear}" printf '%s\n' "$section_output" echo "" fi else - echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" + echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" echo "" fi @@ -4838,12 +4838,12 @@ DisplayPage7() section_output="$(attachedwificlients "$ifname52")" if [ -n "$section_output" ] && \ ! echo "$section_output" | grep -q "No Devices Connected"; then - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz (2) ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname52 ${CClear}" + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz (2) ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname52 ${CClear}" printf '%s\n' "$section_output" echo "" fi else - echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz (2) ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" + echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz (2) ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" echo "" fi fi @@ -4860,12 +4860,12 @@ DisplayPage7() section_output="$(attachedwificlients "$ifname6")" if [ -n "$section_output" ] && \ ! echo "$section_output" | grep -q "No Devices Connected"; then - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname6 ${CClear}" + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname6 ${CClear}" printf '%s\n' "$section_output" echo "" fi else - echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" + echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" echo "" fi fi @@ -4880,12 +4880,12 @@ DisplayPage7() section_output="$(attachedwificlients "$ifname62")" if [ -n "$section_output" ] && \ ! echo "$section_output" | grep -q "No Devices Connected"; then - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz (2) ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname62 ${CClear}" + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz (2) ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname62 ${CClear}" printf '%s\n' "$section_output" echo "" fi else - echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz (2) ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" + echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz (2) ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" echo "" fi fi @@ -4915,7 +4915,9 @@ DisplayPage7() guestlabel="Local Wi-Fi" fi - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}${guestlabel}: ${CGreen}${guestssid}${CWhite} ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $guestiface ${CClear}" + echo -en "${InvGreen} ${CClear}${InvDkGray} ${CWhite}${guestlabel}: ${CGreen}" + printf "%-32s" ${guestssid} + echo -e "${CWhite} ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $guestiface ${CClear}" attachedguestclients "$guestiface" echo "" @@ -4923,12 +4925,12 @@ DisplayPage7() for vlanlabels in $(nvram get apg_ifnames) do - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local VLAN/AiMesh VLAN ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $vlanlabels ${CClear}" + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local VLAN/AiMesh VLAN ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $vlanlabels ${CClear}" attachedvlanclients "$vlanlabels" echo "" done - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local LAN/Non-VLAN AiMesh ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: br0 ${CClear}" + echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local LAN/Non-VLAN AiMesh ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: br0 ${CClear}" #Remove non-LAN records sed -i -e '/eth0/d' /jffs/addons/rtrmon.d/temparp.txt sed -i -e '/IP address/d' /jffs/addons/rtrmon.d/temparp.txt @@ -4990,7 +4992,7 @@ attachedwificlients () { iface="$1" rm -f /jffs/addons/rtrmon.d/wificlients$iface.txt - wl -i $iface assoclist > /jffs/addons/rtrmon.d/wificlients$iface.txt + wl -i $iface assoclist > /jffs/addons/rtrmon.d/wificlients$iface.txt 2>/dev/null maxclientcount=$(cat /jffs/addons/rtrmon.d/wificlients$iface.txt | wc -l) rm -f /jffs/addons/rtrmon.d/clientlist$iface.txt dhcpleases="$(read_all_dhcp_leases)" @@ -5160,7 +5162,7 @@ attachedwificlients () attachedguestclients() { iface="$1" rm -f /jffs/addons/rtrmon.d/wificlients$iface.txt - wl -i "$iface" assoclist > /jffs/addons/rtrmon.d/wificlients$iface.txt + wl -i "$iface" assoclist > /jffs/addons/rtrmon.d/wificlients$iface.txt 2>/dev/null maxclientcount=$(cat /jffs/addons/rtrmon.d/wificlients$iface.txt | wc -l) rm -f /jffs/addons/rtrmon.d/clientlist$iface.txt dhcpleases="$(read_all_dhcp_leases)" From 7473af8d7402ac8e78d38a5152bf073e0452fb17 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Fri, 5 Dec 2025 22:46:46 -0500 Subject: [PATCH 13/62] Update rtrmon.sh --- rtrmon.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtrmon.sh b/rtrmon.sh index 5580f69..ffc2d9b 100644 --- a/rtrmon.sh +++ b/rtrmon.sh @@ -208,7 +208,7 @@ showheader() #Display RTRMON client header echo -en "${InvGreen} ${InvDkGray}${CWhite} RTRMON - v" printf "%-8s" $Version - echo -e " ${CGreen}(S)${CWhite}how/${CGreen}(H)${CWhite}ide Operations Menu ${InvDkGray} $tzspaces$(date) ${CClear}" + echo -e " ${CGreen}(S)${CWhite}how/${CGreen}(H)${CWhite}ide Operations Menu ${InvDkGray} $tzspaces$(date +"%a %b %d, %Y %H:%M:%S %Z %z") ${CClear}" } # ------------------------------------------------------------------------------------------------------------------------- From b5fe7b1f7b6100a4af634cf332e3b57802bf47bf Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Fri, 5 Dec 2025 22:48:31 -0500 Subject: [PATCH 14/62] Update changelog.txt --- changelog.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/changelog.txt b/changelog.txt index 9e45681..cb2188b 100644 --- a/changelog.txt +++ b/changelog.txt @@ -12,6 +12,10 @@ v2.2.4b - (TBA) left out an optimization that affects vpn/wg connections that are using private IPs, and was causing a 1min delay when RTRMON started up. I got this added back in, and is launching successfully again. Thanks to @visortgw for the report! + - PATCH: Changed the date/time to include the offset alongside the timezone. This is to give + more visibility for those who aren't assigned a standard timezone name, and in some cases + would fall back to using "GMT". Thanks to @Tarek Yag for reporting this, and for @EmeraldDeer + providing a deep dive into the date command options. - PATCH: Various spacing tweaks to ensure alignment of required data elements. That's right. I blame the OCD. From d1c19171dc21e1b90be1cccb7304d0c3b3bf0ab0 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Fri, 5 Dec 2025 22:57:14 -0500 Subject: [PATCH 15/62] Update changelog.txt --- changelog.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index cb2188b..e9eca5b 100644 --- a/changelog.txt +++ b/changelog.txt @@ -6,7 +6,7 @@ v2.2.4b - (TBA) to report things accurately again. RTRMON wouldn't be as awesome as it is without these two incredible gentlemen! :) Thank you! - PATCH: Thanks to a CPU temperature issue report from @fr0s7, it was found that the normal - methods of finding CPU temp readings were no longer working on the RT-BE92U. @Dave14503 came + methods of finding CPU temp readings were no longer working on the RT-BE92U. @dave14305 came to the rescue, and was able to find the correct file for a temp reading. Thank you both! - PATCH: Some oversight on my part... after my efforts to optimize my code, I inadvertently left out an optimization that affects vpn/wg connections that are using private IPs, and was From b9be378f448352d388f8f81a1e1c7a357a1c9fbe Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Sat, 6 Dec 2025 08:43:25 -0500 Subject: [PATCH 16/62] Update rtrmon.sh --- rtrmon.sh | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/rtrmon.sh b/rtrmon.sh index ffc2d9b..6dbefae 100644 --- a/rtrmon.sh +++ b/rtrmon.sh @@ -15,7 +15,7 @@ # # Please use the 'sh rtrmon.sh -setup' command to configure the necessary parameters that match your environment the best! # -# Last Modified: 2025-Dec-5 +# Last Modified: 2025-Dec-6 ########################################################################################################################### #Preferred standard router binaries path @@ -24,7 +24,7 @@ export PATH="/sbin:/bin:/usr/sbin:/usr/bin:$PATH" # ------------------------------------------------------------------------------------------------------------------------- # System Variables (Do not change beyond this point or this may change the programs ability to function correctly) # ------------------------------------------------------------------------------------------------------------------------- -Version="2.2.4b1" +Version="2.2.4b2" Beta=1 ScreenshotMode=0 LOGFILE="/jffs/addons/rtrmon.d/rtrmon.log" # Logfile path/name that captures important date/time events - change @@ -4664,7 +4664,7 @@ if [ "$NCView" = "WG" ] ##------------------------------------------## ## Modified by ExtremeFiretop [2025-Dec-03] ## ##------------------------------------------## -# This function displays the stats UI for page 3 +# This function displays the stats UI for page 7 DisplayPage7() { clear @@ -5022,6 +5022,8 @@ attachedwificlients () txratekbps=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rate of last tx pkt:/ {print $6}') 2>/dev/null rxratekbps=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rate of last rx pkt:/ {print $6}') 2>/dev/null sigstrength=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/smoothed rssi:/ {print $3}') 2>/dev/null + chanspec=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/chanspec/ {print $2}') 2>/dev/null + maclower=$(echo "$clientmac" | awk '{print tolower($0)}') 2>/dev/null # For WiFi 7 / MLO clients the MAC used by wl (assoclist) may NOT be @@ -5132,7 +5134,7 @@ attachedwificlients () # Remove this canonical MAC from the temp ARP table sed -i -e '/'$canonlower'/d' /jffs/addons/rtrmon.d/temparp.txt - echo "$clientname,$paddedclientip,$canonupper,$conntime,$txtotalgb,$rxtotalgb,$txratembps,$rxratembps,$sigstrength" \ + echo "$clientname,$paddedclientip,$canonupper,$conntime,$txtotalgb,$rxtotalgb,$txratembps,$rxratembps,$sigstrength,$chanspec" \ >> /jffs/addons/rtrmon.d/clientlist$iface.txt fi done @@ -5140,7 +5142,7 @@ attachedwificlients () if [ -f "/jffs/addons/rtrmon.d/clientlist$iface.txt" ]; then if [ $maxclientcount -ge 1 ]; then sort -f -d -o /jffs/addons/rtrmon.d/clientlist$iface.txt -k "$SortbyNum" -t , /jffs/addons/rtrmon.d/clientlist$iface.txt 2>/dev/null - column -t -s',' -o' | ' -N Name,IP,MAC,Uptime,"TX GB","RX GB","TX Mbps","RX Mbps","Sig" /jffs/addons/rtrmon.d/clientlist$iface.txt | sed 's/^/ /' + column -t -s',' -o' | ' -N Name,IP,MAC,Uptime,"TX GB","RX GB","TX Mbps","RX Mbps","Sig","Band" /jffs/addons/rtrmon.d/clientlist$iface.txt | sed 's/^/ /' else echo -e " No Devices Connected" fi From 158ea9efeb5bc0e47ea4872c89f5ac9b0ad930a2 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Sat, 6 Dec 2025 08:43:43 -0500 Subject: [PATCH 17/62] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4a0fbcb..f9a77a0 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# RTRMON v2.2.4 +# RTRMON v2.2.4b2 Asus-Merlin Router Monitor by Viktor Jaep, 2022-2025 -Updated on 2025-Dec-04 +Updated on 2025-Dec-06 --- From dcac584ab51d0a9067f87e672afb1fd1b1f87948 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Sat, 6 Dec 2025 08:45:33 -0500 Subject: [PATCH 18/62] Update changelog.txt --- changelog.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index e9eca5b..f9478f9 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,4 +1,4 @@ -v2.2.4b - (TBA) +v2.2.4b2 - (TBA) - PATCH: HUGE HUGE THANKS to both @ExtremeFiretop and @visortgw for their help getting the wired/wireless client page (#7) working again. Apparently something had broken between a firmware release that seemed to be causing some incorrect reporting on this page. Both these @@ -18,6 +18,8 @@ v2.2.4b - (TBA) providing a deep dive into the date command options. - PATCH: Various spacing tweaks to ensure alignment of required data elements. That's right. I blame the OCD. + - PATCH: Added the wireless channel spec to the table output list per @visortgw request. We + may need to start widening the UI here soon! :) v2.2.3 - (November 16, 2025) - PATCH: Modified how the memory stats are being captured, and is now more in line with the From ff9872f151eaefdd1c0cc636cd455510e04e70a6 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Sat, 6 Dec 2025 09:12:39 -0500 Subject: [PATCH 19/62] Update rtrmon.sh --- rtrmon.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/rtrmon.sh b/rtrmon.sh index 6dbefae..df2af75 100644 --- a/rtrmon.sh +++ b/rtrmon.sh @@ -5194,6 +5194,7 @@ attachedguestclients() { txratekbps=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rate of last tx pkt:/ {print $6}') 2>/dev/null rxratekbps=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rate of last rx pkt:/ {print $6}') 2>/dev/null sigstrength=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/smoothed rssi:/ {print $3}') 2>/dev/null + chanspec=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/chanspec/ {print $2}') 2>/dev/null maclower=$(echo "$clientmac" | awk '{print tolower($0)}') 2>/dev/null # Start with assoc MAC as canonical, may override with ARP MAC (WiFi7 / MLO case). @@ -5319,7 +5320,7 @@ attachedguestclients() { sed -i -e '/'$canonlower'/d' /jffs/addons/rtrmon.d/temparp.txt fi - echo "$clientname,$paddedclientip,$canonupper,$conntime,$txtotalgb,$rxtotalgb,$txratembps,$rxratembps,$sigstrength" \ + echo "$clientname,$paddedclientip,$canonupper,$conntime,$txtotalgb,$rxtotalgb,$txratembps,$rxratembps,$sigstrength,$chanspec" \ >> /jffs/addons/rtrmon.d/clientlist$iface.txt fi done @@ -5327,7 +5328,7 @@ attachedguestclients() { if [ -f "/jffs/addons/rtrmon.d/clientlist$iface.txt" ]; then if [ $maxclientcount -ge 1 ]; then sort -f -d -o /jffs/addons/rtrmon.d/clientlist$iface.txt -k "$SortbyNum" -t , /jffs/addons/rtrmon.d/clientlist$iface.txt 2>/dev/null - column -t -s',' -o' | ' -N Name,IP,MAC,Uptime,"TX GB","RX GB","TX Mbps","RX Mbps","Sig" /jffs/addons/rtrmon.d/clientlist$iface.txt | sed 's/^/ /' + column -t -s',' -o' | ' -N Name,IP,MAC,Uptime,"TX GB","RX GB","TX Mbps","RX Mbps","Sig","Band" /jffs/addons/rtrmon.d/clientlist$iface.txt | sed 's/^/ /' else echo -e " No Devices Connected" fi @@ -5395,6 +5396,7 @@ attachedvlanclients() { txratekbps=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/rate of last tx pkt:/ {print $6}') 2>/dev/null rxratekbps=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/rate of last rx pkt:/ {print $6}') 2>/dev/null sigstrength=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/smoothed rssi:/ {print $3}') 2>/dev/null + chanspec=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/chanspec/ {print $2}') 2>/dev/null maclower=$(echo "$clientmac" | awk '{print tolower($0)}') 2>/dev/null lookup_mac=$(get_lookup_mac "$maclower" "$dhcpleases") @@ -5465,7 +5467,7 @@ attachedvlanclients() { if [ "$conntime" = "AiMesh" ]; then echo "$clientname,$paddedclientip,$macupper,$conntime" >> /jffs/addons/rtrmon.d/vlanclients$iface.txt else - echo "$clientname,$paddedclientip,$macupper,$conntime,$txtotalgb,$rxtotalgb,$txratembps,$rxratembps,$sigstrength" >> /jffs/addons/rtrmon.d/vlanclients$iface.txt + echo "$clientname,$paddedclientip,$macupper,$conntime,$txtotalgb,$rxtotalgb,$txratembps,$rxratembps,$sigstrength,$chanspec" >> /jffs/addons/rtrmon.d/vlanclients$iface.txt fi fi done @@ -5475,7 +5477,7 @@ attachedvlanclients() { sort -f -d -t ',' -k "$SortbyNum" -k 4,4 /jffs/addons/rtrmon.d/vlanclients$iface.txt 2>/dev/null | \ awk -F',' -v OFS=',' '{if ($4 ~ /AiMesh/) {a[i++]=$0} else {print $0}} END {for (j=0; j /tmp/vlanclients_sorted.txt mv /tmp/vlanclients_sorted.txt /jffs/addons/rtrmon.d/vlanclients$iface.txt - column -t -s',' -o' | ' -N Name,IP,MAC,Uptime,"TX GB","RX GB","TX Mbps","RX Mbps","Sig" /jffs/addons/rtrmon.d/vlanclients$iface.txt | sed 's/^/ /' + column -t -s',' -o' | ' -N Name,IP,MAC,Uptime,"TX GB","RX GB","TX Mbps","RX Mbps","Sig","Band" /jffs/addons/rtrmon.d/vlanclients$iface.txt | sed 's/^/ /' else echo -e " No Devices Connected" fi From 5e73053ca02df035e20ebfc1b1d59c62adab4f2e Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Sat, 6 Dec 2025 10:29:30 -0500 Subject: [PATCH 20/62] Update rtrmon.sh --- rtrmon.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtrmon.sh b/rtrmon.sh index df2af75..4cb505d 100644 --- a/rtrmon.sh +++ b/rtrmon.sh @@ -5396,7 +5396,7 @@ attachedvlanclients() { txratekbps=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/rate of last tx pkt:/ {print $6}') 2>/dev/null rxratekbps=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/rate of last rx pkt:/ {print $6}') 2>/dev/null sigstrength=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/smoothed rssi:/ {print $3}') 2>/dev/null - chanspec=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/chanspec/ {print $2}') 2>/dev/null + chanspec=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/chanspec/ {print $2}') 2>/dev/null maclower=$(echo "$clientmac" | awk '{print tolower($0)}') 2>/dev/null lookup_mac=$(get_lookup_mac "$maclower" "$dhcpleases") From 0d9205f8b02bbeb3df02dd71f1b0c2626d1aeb2f Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Sun, 7 Dec 2025 22:16:40 -0500 Subject: [PATCH 21/62] Update rtrmon.sh --- rtrmon.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/rtrmon.sh b/rtrmon.sh index 4cb505d..5f564e8 100644 --- a/rtrmon.sh +++ b/rtrmon.sh @@ -15,7 +15,7 @@ # # Please use the 'sh rtrmon.sh -setup' command to configure the necessary parameters that match your environment the best! # -# Last Modified: 2025-Dec-6 +# Last Modified: 2025-Dec-7 ########################################################################################################################### #Preferred standard router binaries path @@ -24,7 +24,7 @@ export PATH="/sbin:/bin:/usr/sbin:/usr/bin:$PATH" # ------------------------------------------------------------------------------------------------------------------------- # System Variables (Do not change beyond this point or this may change the programs ability to function correctly) # ------------------------------------------------------------------------------------------------------------------------- -Version="2.2.4b2" +Version="2.2.4b3" Beta=1 ScreenshotMode=0 LOGFILE="/jffs/addons/rtrmon.d/rtrmon.log" # Logfile path/name that captures important date/time events - change @@ -5346,6 +5346,7 @@ attachedvlanclients() { iface="$1" vlansfound=1 maxclientcount=$(cat /jffs/addons/rtrmon.d/temparpvlan.txt | wc -l) + maxclientcount=$((maxclientcount-1)) #To account for header row rm -f /jffs/addons/rtrmon.d/vlanclients$iface.txt dhcpleases="$(read_all_dhcp_leases)" local clients @@ -5353,7 +5354,7 @@ attachedvlanclients() { local maxextractcount maxextractcount=$(echo "$clients" | awk -F'<' '{print NF}') - local clientcount=0 + local clientcount=1 #Increased to 1 from 0, to account for header row while [ $clientcount -le $maxclientcount ] do clientname="" @@ -5361,7 +5362,7 @@ attachedvlanclients() { clientip="" paddedclientip="" interface_name="" - clientcount=$((clientcount+1)) + clientcount=$((clientcount+1)) #This would make it start on row 2, skipping header row local clientmac=$(awk 'NR=='$clientcount' {print $4}' /jffs/addons/rtrmon.d/temparpvlan.txt | xargs) if [ -z "$clientmac" ]; then From e308e241315b648abee3e44983fce4b656e2b859 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Tue, 9 Dec 2025 22:21:29 -0500 Subject: [PATCH 22/62] Create netmon-poc.sh --- netmon-poc.sh | 387 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 387 insertions(+) create mode 100644 netmon-poc.sh diff --git a/netmon-poc.sh b/netmon-poc.sh new file mode 100644 index 0000000..bff5e64 --- /dev/null +++ b/netmon-poc.sh @@ -0,0 +1,387 @@ +#!/bin/sh +################################################################################ +# Asus-Merlin Network Client Monitor +# Compatible with GT-AX6000 running Asus-Merlin Firmware 3006.102.6 +# Identifies all active interfaces and connected clients across bands +################################################################################ + +# Enable strict error handling +set -u + +################################################################################ +# CONSTANTS AND CONFIGURATION +################################################################################ +NVRAM="nvram" +WL="wl" +ARP="arp" +IFCONFIG="ifconfig" +CAT="cat" + +################################################################################ +# UTILITY FUNCTIONS +################################################################################ + +# Check if IP is a local/private address +is_local_ip() { + local ip="$1" + + # Check for private IP ranges + case "${ip}" in + 10.*) return 0 ;; + 192.168.*) return 0 ;; + 172.1[6-9].*) return 0 ;; + 172.2[0-9].*) return 0 ;; + 172.3[0-1].*) return 0 ;; + 169.254.*) return 0 ;; # Link-local + 127.*) return 0 ;; # Loopback + *) return 1 ;; + esac +} + +# Get all active wireless interfaces +get_wireless_interfaces() { + ${IFCONFIG} | grep '^eth[0-9]\|^wl[0-9]' | awk '{print $1}' | while read iface; do + # Verify interface actually has wireless capability + if ${WL} -i "${iface}" status >/dev/null 2>&1; then + echo "${iface}" + fi + done | sort -u +} + +# Get interface type and band information +get_interface_info() { + local iface="$1" + local band="" + local type="" + local guest_ssid="" + + # Check if it's a guest network interface (e.g., wl0.1, wl1.1) + if echo "${iface}" | grep '\.' >/dev/null 2>&1; then + local base_iface=$(echo "${iface}" | cut -d'.' -f1) + local guest_num=$(echo "${iface}" | cut -d'.' -f2) + + # Determine band from base interface + case "${base_iface}" in + wl0|eth6) band="2.4GHz" ;; + wl1|eth7) band="5.0GHz" ;; + wl2|eth8) band="6.0GHz" ;; + esac + + # Get guest SSID + guest_ssid=$(${NVRAM} get ${base_iface}.${guest_num}_ssid 2>/dev/null || echo "Guest Network") + type="guest" + echo "${type}|${band}|${guest_ssid}" + return + fi + + # Determine main interface type + case "${iface}" in + eth6|wl0) band="2.4GHz"; type="main" ;; + eth7|wl1) band="5.0GHz"; type="main" ;; + eth8|wl2) band="6.0GHz"; type="main" ;; + br0) type="lan" ;; + *) type="unknown" ;; + esac + + echo "${type}|${band}|" +} + +# Convert seconds to hours:minutes format +format_uptime() { + local seconds="$1" + local hours=$((seconds / 3600)) + local minutes=$(((seconds % 3600) / 60)) + printf "%02dh:%02dm" "${hours}" "${minutes}" +} + +# Convert bytes to GB +bytes_to_gb() { + local bytes="$1" + if [ "${bytes}" -eq 0 ] 2>/dev/null; then + echo "0.00" + else + echo "${bytes}" | awk '{printf "%.2f", $1/1024/1024/1024}' + fi +} + +# Get IP address for a MAC from ARP table +get_ip_from_mac() { + local mac="$1" + local ip="" + + # Try /proc/net/arp first (more reliable) + if [ -f /proc/net/arp ]; then + ip=$(grep -i "${mac}" /proc/net/arp 2>/dev/null | awk '{print $1}' | head -n1) + fi + + # Fallback to arp command + if [ -z "${ip}" ]; then + ip=$(${ARP} -n 2>/dev/null | grep -i "${mac}" | awk '{print $1}' | head -n1) + fi + + # Return IP or Unknown + if [ -z "${ip}" ] || [ "${ip}" = "?" ]; then + echo "Unknown" + else + echo "${ip}" + fi +} + +# Get hostname from dnsmasq leases and nvram - MAC-specific +get_hostname() { + local mac="$1" + local ip="$2" + local hostname="" + local mac_normalized=$(echo "${mac}" | tr 'A-F' 'a-f') + + # Try dnsmasq leases first - match by MAC + if [ -f /var/lib/misc/dnsmasq.leases ]; then + hostname=$(awk -v mac="${mac_normalized}" 'tolower($2) == mac {print $4; exit}' /var/lib/misc/dnsmasq.leases 2>/dev/null) + fi + + # Try matching by IP in dnsmasq if MAC didn't work + if [ -z "${hostname}" ] || [ "${hostname}" = "*" ]; then + if [ -f /var/lib/misc/dnsmasq.leases ] && [ "${ip}" != "Unknown" ]; then + hostname=$(awk -v ip="${ip}" '$3 == ip {print $4; exit}' /var/lib/misc/dnsmasq.leases 2>/dev/null) + fi + fi + + # Try nvram custom_clientlist - format is MAC>IP + if [ -z "${hostname}" ] || [ "${hostname}" = "*" ]; then + local clientlist=$(${NVRAM} get custom_clientlist 2>/dev/null) + if [ -n "${clientlist}" ]; then + # Parse custom_clientlist entries + hostname=$(echo "${clientlist}" | tr '<' '\n' | grep -i "${mac}" | cut -d'>' -f1 | head -n1) + fi + fi + + # Fallback to networkmap data + if [ -z "${hostname}" ] || [ "${hostname}" = "*" ]; then + if [ -f /var/lib/misc/networkmap.log ]; then + hostname=$(grep -i "${mac}" /var/lib/misc/networkmap.log 2>/dev/null | awk '{print $1}' | head -n1) + fi + fi + + # Last resort: use MAC address as identifier + if [ -z "${hostname}" ] || [ "${hostname}" = "*" ]; then + hostname="${mac}" + fi + + echo "${hostname}" +} + +################################################################################ +# WIRELESS CLIENT ENUMERATION +################################################################################ + +# Get wireless clients for a specific interface +get_wireless_clients() { + local iface="$1" + + # Use wl to get associated stations - extract MAC addresses + ${WL} -i "${iface}" assoclist 2>/dev/null | awk '/assoclist/ {print $2}' +} + +# Get detailed wireless client information +get_wireless_client_details() { + local iface="$1" + local mac="$2" + local ip="" + local hostname="" + local uptime="0" + local tx_bytes="0" + local rx_bytes="0" + local tx_rate="0" + local rx_rate="0" + local signal="0" + local bandwidth="" + + # Get IP from MAC address + ip=$(get_ip_from_mac "${mac}") + + # Get hostname + hostname=$(get_hostname "${mac}" "${ip}") + + # Get wireless statistics using wl sta_info + if sta_info=$(${WL} -i "${iface}" sta_info "${mac}" 2>/dev/null); then + # Parse uptime (in seconds) + uptime=$(echo "${sta_info}" | grep 'in network' | awk '{for(i=1;i<=NF;i++){if($i=="network"){print $(i+1); exit}}}') + [ -z "${uptime}" ] && uptime="0" + + # Parse signal strength + signal=$(echo "${sta_info}" | grep 'RSSI:' | head -n1 | awk '{print $2}') + [ -z "${signal}" ] && signal="0" + + # Parse rates (in Kbps, convert to Mbps) + tx_rate=$(echo "${sta_info}" | grep 'rate of last tx pkt:' | awk '{print $6}') + rx_rate=$(echo "${sta_info}" | grep 'rate of last rx pkt:' | awk '{print $6}') + [ -z "${tx_rate}" ] && tx_rate="0" + [ -z "${rx_rate}" ] && rx_rate="0" + + # Parse bandwidth/channel width + bandwidth=$(echo "${sta_info}" | grep 'chanspec:' | head -n1 | awk '{for(i=1;i<=NF;i++){if($i=="chanspec:"){for(j=i+1;j<=NF;j++){if($j ~ /\)$/){print $(i+1); exit} else {printf "%s ", $(i+1); i++}}}}}') + [ -z "${bandwidth}" ] && bandwidth="Unknown" + fi + + # Get traffic statistics from /proc/net/nf_conntrack (approximation) + if [ "${ip}" != "Unknown" ] && [ -f /proc/net/nf_conntrack ]; then + tx_bytes=$(grep "${ip}" /proc/net/nf_conntrack 2>/dev/null | awk '{sum+=$1} END {print sum+0}') + rx_bytes=$(grep "${ip}" /proc/net/nf_conntrack 2>/dev/null | awk '{sum+=$2} END {print sum+0}') + [ -z "${tx_bytes}" ] && tx_bytes="0" + [ -z "${rx_bytes}" ] && rx_bytes="0" + fi + + # Format output + printf " %-14s | %-15s | %-17s | %7s | %5s | %5s | %7.1f | %7.1f | %3s | %s\n" \ + "${hostname}" \ + "${ip}" \ + "${mac}" \ + "$(format_uptime ${uptime})" \ + "$(bytes_to_gb ${tx_bytes})" \ + "$(bytes_to_gb ${rx_bytes})" \ + "$(echo ${tx_rate} | awk '{printf "%.1f", $1/1000}')" \ + "$(echo ${rx_rate} | awk '{printf "%.1f", $1/1000}')" \ + "${signal}" \ + "${bandwidth}" +} + +################################################################################ +# LAN CLIENT ENUMERATION +################################################################################ + +# Get LAN/br0 clients (non-wireless) +get_lan_clients() { + local wireless_macs="" + local iface + local temp_file="/tmp/lan_clients_$$.tmp" + + # Collect all wireless MACs to exclude them + for iface in $(get_wireless_interfaces); do + local clients=$(get_wireless_clients "${iface}") + if [ -n "${clients}" ]; then + wireless_macs="${wireless_macs} ${clients}" + fi + done + + # Normalize wireless MACs to lowercase + wireless_macs=$(echo "${wireless_macs}" | tr 'A-F' 'a-f') + + # Get all ARP entries from /proc/net/arp and store in temp file + if [ -f /proc/net/arp ]; then + ${CAT} /proc/net/arp | awk 'NR>1 && $3!="0x0" && $4!="00:00:00:00:00:00" {print $1, $4}' > "${temp_file}" + else + # Fallback to arp command + ${ARP} -n 2>/dev/null | awk 'NR>1 && $1!="?" {print $1, $3}' > "${temp_file}" + fi + + # Process ARP entries + while read ip mac; do + # Skip empty lines + [ -z "${mac}" ] || [ -z "${ip}" ] && continue + [ "${ip}" = "IP" ] && continue + + # Filter out non-local IP addresses + if ! is_local_ip "${ip}"; then + continue + fi + + # Normalize MAC to lowercase + local mac_normalized=$(echo "${mac}" | tr 'A-F' 'a-f') + + # Skip if MAC is in wireless list + local is_wireless=0 + for wmac in ${wireless_macs}; do + if [ "${mac_normalized}" = "${wmac}" ]; then + is_wireless=1 + break + fi + done + + if [ ${is_wireless} -eq 0 ]; then + local hostname=$(get_hostname "${mac}" "${ip}") + printf " %-14s | %-15s | %s\n" "${hostname}" "${ip}" "${mac}" + fi + done < "${temp_file}" | sort -u + + # Clean up temp file + rm -f "${temp_file}" +} + +################################################################################ +# MAIN DISPLAY ROUTINE +################################################################################ + +display_network_clients() { + local iface + local info_str + local iface_type + local band + local guest_ssid + local client_count + + echo "" + echo "================================================================================" + echo " ASUS GT-AX6000 Network Client Monitor" + echo " Asus-Merlin Firmware 3006.102.6" + echo " Generated: $(date '+%Y-%m-%d %H:%M:%S')" + echo "================================================================================" + echo "" + + # Process each wireless interface + for iface in $(get_wireless_interfaces); do + info_str=$(get_interface_info "${iface}") + iface_type=$(echo "${info_str}" | cut -d'|' -f1) + band=$(echo "${info_str}" | cut -d'|' -f2) + guest_ssid=$(echo "${info_str}" | cut -d'|' -f3) + + # Skip unknown interfaces + [ "${iface_type}" = "unknown" ] && continue + + # Get clients for this interface + client_count=0 + client_list=$(get_wireless_clients "${iface}") + + if [ -n "${client_list}" ]; then + client_count=$(echo "${client_list}" | wc -l) + fi + + # Display header based on interface type + if [ "${iface_type}" = "guest" ]; then + echo " Guest Wi-Fi: ${guest_ssid} - IFace: ${iface}" + elif [ "${iface_type}" = "main" ]; then + echo " Local ${band} - IFace: ${iface}" + fi + + # Display column headers for wireless + if [ "${iface_type}" = "main" ] || [ "${iface_type}" = "guest" ]; then + printf " %-14s | %-15s | %-17s | %7s | %5s | %5s | %7s | %7s | %3s | %s\n" \ + "Name" "IP" "MAC" "Uptime" "TX GB" "RX GB" "TX Mbps" "RX Mbps" "Sig" "Band" + + # Display clients + if [ -n "${client_list}" ]; then + for mac in ${client_list}; do + get_wireless_client_details "${iface}" "${mac}" + done + else + echo " No clients connected" + fi + echo "" + fi + done + + # Display LAN/br0 clients + echo " Local LAN/Non-VLAN AiMesh - IFace: br0" + printf " %-14s | %-15s | %s\n" "Name" "IP" "MAC" + get_lan_clients + echo "" + echo "================================================================================" +} + +################################################################################ +# ENTRY POINT +################################################################################ + +# Execute main routine +display_network_clients + +exit 0 From 1e294c2b628cb03d1ca09557b058372dcbd95e4f Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Wed, 10 Dec 2025 07:17:18 -0500 Subject: [PATCH 23/62] Update netmon-poc.sh --- netmon-poc.sh | 140 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 122 insertions(+), 18 deletions(-) diff --git a/netmon-poc.sh b/netmon-poc.sh index bff5e64..e3ff242 100644 --- a/netmon-poc.sh +++ b/netmon-poc.sh @@ -1,7 +1,7 @@ #!/bin/sh ################################################################################ # Asus-Merlin Network Client Monitor -# Compatible with GT-AX6000 running Asus-Merlin Firmware 3006.102.6 +# Compatible with multiple Asus router models running Asus-Merlin Firmware # Identifies all active interfaces and connected clients across bands ################################################################################ @@ -17,6 +17,72 @@ ARP="arp" IFCONFIG="ifconfig" CAT="cat" +# Radio configuration variables +IFNAME_24="" +IFNAME_5="" +IFNAME_5_2="" +IFNAME_6="" +IFNAME_6_2="" + +################################################################################ +# ROUTER MODEL DETECTION AND INTERFACE MAPPING +################################################################################ + +# Detect router model and configure interface mappings +detect_router_model() { + local router_model=$(${NVRAM} get productid 2>/dev/null) + [ -z "${router_model}" ] && router_model=$(${NVRAM} get model 2>/dev/null) + + echo "Detected Router Model: ${router_model}" >&2 + + # Determine radio configuration based on router model + case "${router_model}" in + # Four-band routers: 5GHz, 5GHz, 6GHz, 2.4GHz (wl0=5, wl1=5, wl2=6, wl3=2.4) + GT-AXE16000|GT-BE98) + IFNAME_5=$(${NVRAM} get wl0_ifname 2>/dev/null) + IFNAME_5_2=$(${NVRAM} get wl1_ifname 2>/dev/null) + IFNAME_6=$(${NVRAM} get wl2_ifname 2>/dev/null) + IFNAME_24=$(${NVRAM} get wl3_ifname 2>/dev/null) + ;; + + # Four-band routers: 5GHz, 6GHz, 6GHz, 2.4GHz (wl0=5, wl1=6, wl2=6, wl3=2.4) + GT-BE98_Pro) + IFNAME_5=$(${NVRAM} get wl0_ifname 2>/dev/null) + IFNAME_6=$(${NVRAM} get wl1_ifname 2>/dev/null) + IFNAME_6_2=$(${NVRAM} get wl2_ifname 2>/dev/null) + IFNAME_24=$(${NVRAM} get wl3_ifname 2>/dev/null) + ;; + + # Three-band routers: 2.4GHz, 5GHz, 6GHz (wl0=2.4, wl1=5, wl2=6) + GT-AXE11000|ZenWiFi_ET8|RT-BE96U|RT-BE92U) + IFNAME_24=$(${NVRAM} get wl0_ifname 2>/dev/null) + IFNAME_5=$(${NVRAM} get wl1_ifname 2>/dev/null) + IFNAME_6=$(${NVRAM} get wl2_ifname 2>/dev/null) + ;; + + # Three-band routers: 2.4GHz, 5GHz, 5GHz (wl0=2.4, wl1=5, wl2=5) + GT-AX11000_Pro|GT-AX11000|ZenWiFi_Pro_XT12|ZenWiFi_XT8) + IFNAME_24=$(${NVRAM} get wl0_ifname 2>/dev/null) + IFNAME_5=$(${NVRAM} get wl1_ifname 2>/dev/null) + IFNAME_5_2=$(${NVRAM} get wl2_ifname 2>/dev/null) + ;; + + # Default two-band routers: 2.4GHz, 5GHz (wl0=2.4, wl1=5) + *) + IFNAME_24=$(${NVRAM} get wl0_ifname 2>/dev/null) + IFNAME_5=$(${NVRAM} get wl1_ifname 2>/dev/null) + ;; + esac + + # Log detected interfaces + echo "Interface Mapping:" >&2 + [ -n "${IFNAME_24}" ] && echo " 2.4GHz: ${IFNAME_24}" >&2 + [ -n "${IFNAME_5}" ] && echo " 5.0GHz: ${IFNAME_5}" >&2 + [ -n "${IFNAME_5_2}" ] && echo " 5.0GHz-2: ${IFNAME_5_2}" >&2 + [ -n "${IFNAME_6}" ] && echo " 6.0GHz: ${IFNAME_6}" >&2 + [ -n "${IFNAME_6_2}" ] && echo " 6.0GHz-2: ${IFNAME_6_2}" >&2 +} + ################################################################################ # UTILITY FUNCTIONS ################################################################################ @@ -48,6 +114,26 @@ get_wireless_interfaces() { done | sort -u } +# Get band name from interface name based on detected configuration +get_band_from_interface() { + local iface="$1" + + # Check against detected interface names + if [ "${iface}" = "${IFNAME_24}" ]; then + echo "2.4GHz" + elif [ "${iface}" = "${IFNAME_5}" ]; then + echo "5.0GHz" + elif [ -n "${IFNAME_5_2}" ] && [ "${iface}" = "${IFNAME_5_2}" ]; then + echo "5.0GHz-2" + elif [ -n "${IFNAME_6}" ] && [ "${iface}" = "${IFNAME_6}" ]; then + echo "6.0GHz" + elif [ -n "${IFNAME_6_2}" ] && [ "${iface}" = "${IFNAME_6_2}" ]; then + echo "6.0GHz-2" + else + echo "" + fi +} + # Get interface type and band information get_interface_info() { local iface="$1" @@ -60,28 +146,41 @@ get_interface_info() { local base_iface=$(echo "${iface}" | cut -d'.' -f1) local guest_num=$(echo "${iface}" | cut -d'.' -f2) - # Determine band from base interface - case "${base_iface}" in - wl0|eth6) band="2.4GHz" ;; - wl1|eth7) band="5.0GHz" ;; - wl2|eth8) band="6.0GHz" ;; - esac + # Determine band from base interface using detected mappings + band=$(get_band_from_interface "${base_iface}") # Get guest SSID - guest_ssid=$(${NVRAM} get ${base_iface}.${guest_num}_ssid 2>/dev/null || echo "Guest Network") + # Need to find which wl unit corresponds to this interface + local wl_unit="" + for unit in 0 1 2 3; do + local unit_iface=$(${NVRAM} get wl${unit}_ifname 2>/dev/null) + if [ "${unit_iface}" = "${base_iface}" ]; then + wl_unit="${unit}" + break + fi + done + + if [ -n "${wl_unit}" ]; then + guest_ssid=$(${NVRAM} get wl${wl_unit}.${guest_num}_ssid 2>/dev/null || echo "Guest Network") + else + guest_ssid="Guest Network" + fi + type="guest" echo "${type}|${band}|${guest_ssid}" return fi - # Determine main interface type - case "${iface}" in - eth6|wl0) band="2.4GHz"; type="main" ;; - eth7|wl1) band="5.0GHz"; type="main" ;; - eth8|wl2) band="6.0GHz"; type="main" ;; - br0) type="lan" ;; - *) type="unknown" ;; - esac + # Determine main interface type using detected mappings + band=$(get_band_from_interface "${iface}") + + if [ -n "${band}" ]; then + type="main" + elif [ "${iface}" = "br0" ]; then + type="lan" + else + type="unknown" + fi echo "${type}|${band}|" } @@ -321,8 +420,8 @@ display_network_clients() { echo "" echo "================================================================================" - echo " ASUS GT-AX6000 Network Client Monitor" - echo " Asus-Merlin Firmware 3006.102.6" + echo " ASUS Network Client Monitor" + echo " Asus-Merlin Firmware" echo " Generated: $(date '+%Y-%m-%d %H:%M:%S')" echo "================================================================================" echo "" @@ -381,6 +480,11 @@ display_network_clients() { # ENTRY POINT ################################################################################ +clear + +# Detect router model and configure interface mappings +detect_router_model + # Execute main routine display_network_clients From 691ad8637309e69474eb39fbd9f2ee9c66bff884 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Wed, 10 Dec 2025 08:48:53 -0500 Subject: [PATCH 24/62] Fix device name casing in netmon-poc.sh --- netmon-poc.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netmon-poc.sh b/netmon-poc.sh index e3ff242..f0deda0 100644 --- a/netmon-poc.sh +++ b/netmon-poc.sh @@ -46,7 +46,7 @@ detect_router_model() { ;; # Four-band routers: 5GHz, 6GHz, 6GHz, 2.4GHz (wl0=5, wl1=6, wl2=6, wl3=2.4) - GT-BE98_Pro) + GT-BE98_PRO) IFNAME_5=$(${NVRAM} get wl0_ifname 2>/dev/null) IFNAME_6=$(${NVRAM} get wl1_ifname 2>/dev/null) IFNAME_6_2=$(${NVRAM} get wl2_ifname 2>/dev/null) @@ -61,7 +61,7 @@ detect_router_model() { ;; # Three-band routers: 2.4GHz, 5GHz, 5GHz (wl0=2.4, wl1=5, wl2=5) - GT-AX11000_Pro|GT-AX11000|ZenWiFi_Pro_XT12|ZenWiFi_XT8) + GT-AX11000_PRO|GT-AX11000|ZenWiFi_Pro_XT12|ZenWiFi_XT8) IFNAME_24=$(${NVRAM} get wl0_ifname 2>/dev/null) IFNAME_5=$(${NVRAM} get wl1_ifname 2>/dev/null) IFNAME_5_2=$(${NVRAM} get wl2_ifname 2>/dev/null) From 8fb511c3276430e3bf7159ec98886fdafbc7ef2c Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Wed, 10 Dec 2025 19:10:50 -0500 Subject: [PATCH 25/62] Update netmon-poc.sh --- netmon-poc.sh | 309 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 234 insertions(+), 75 deletions(-) diff --git a/netmon-poc.sh b/netmon-poc.sh index f0deda0..d8bb2b9 100644 --- a/netmon-poc.sh +++ b/netmon-poc.sh @@ -46,7 +46,7 @@ detect_router_model() { ;; # Four-band routers: 5GHz, 6GHz, 6GHz, 2.4GHz (wl0=5, wl1=6, wl2=6, wl3=2.4) - GT-BE98_PRO) + GT-BE98_Pro) IFNAME_5=$(${NVRAM} get wl0_ifname 2>/dev/null) IFNAME_6=$(${NVRAM} get wl1_ifname 2>/dev/null) IFNAME_6_2=$(${NVRAM} get wl2_ifname 2>/dev/null) @@ -61,7 +61,7 @@ detect_router_model() { ;; # Three-band routers: 2.4GHz, 5GHz, 5GHz (wl0=2.4, wl1=5, wl2=5) - GT-AX11000_PRO|GT-AX11000|ZenWiFi_Pro_XT12|ZenWiFi_XT8) + GT-AX11000_Pro|GT-AX11000|ZenWiFi_Pro_XT12|ZenWiFi_XT8) IFNAME_24=$(${NVRAM} get wl0_ifname 2>/dev/null) IFNAME_5=$(${NVRAM} get wl1_ifname 2>/dev/null) IFNAME_5_2=$(${NVRAM} get wl2_ifname 2>/dev/null) @@ -98,8 +98,8 @@ is_local_ip() { 172.1[6-9].*) return 0 ;; 172.2[0-9].*) return 0 ;; 172.3[0-1].*) return 0 ;; - 169.254.*) return 0 ;; # Link-local - 127.*) return 0 ;; # Loopback + 169.254.*) return 0 ;; + 127.*) return 0 ;; *) return 1 ;; esac } @@ -107,7 +107,6 @@ is_local_ip() { # Get all active wireless interfaces get_wireless_interfaces() { ${IFCONFIG} | grep '^eth[0-9]\|^wl[0-9]' | awk '{print $1}' | while read iface; do - # Verify interface actually has wireless capability if ${WL} -i "${iface}" status >/dev/null 2>&1; then echo "${iface}" fi @@ -118,7 +117,6 @@ get_wireless_interfaces() { get_band_from_interface() { local iface="$1" - # Check against detected interface names if [ "${iface}" = "${IFNAME_24}" ]; then echo "2.4GHz" elif [ "${iface}" = "${IFNAME_5}" ]; then @@ -141,27 +139,34 @@ get_interface_info() { local type="" local guest_ssid="" - # Check if it's a guest network interface (e.g., wl0.1, wl1.1) - if echo "${iface}" | grep '\.' >/dev/null 2>&1; then + echo "${iface}" | grep '\.' >/dev/null 2>&1 + if [ $? -eq 0 ]; then local base_iface=$(echo "${iface}" | cut -d'.' -f1) local guest_num=$(echo "${iface}" | cut -d'.' -f2) - # Determine band from base interface using detected mappings band=$(get_band_from_interface "${base_iface}") - # Get guest SSID - # Need to find which wl unit corresponds to this interface local wl_unit="" - for unit in 0 1 2 3; do - local unit_iface=$(${NVRAM} get wl${unit}_ifname 2>/dev/null) - if [ "${unit_iface}" = "${base_iface}" ]; then - wl_unit="${unit}" - break - fi - done + + echo "${base_iface}" | grep '^wl[0-9]$' >/dev/null 2>&1 + if [ $? -eq 0 ]; then + wl_unit=$(echo "${base_iface}" | grep -o '[0-9]') + else + local unit + for unit in 0 1 2 3; do + local unit_iface=$(${NVRAM} get wl${unit}_ifname 2>/dev/null) + if [ "${unit_iface}" = "${base_iface}" ]; then + wl_unit="${unit}" + break + fi + done + fi if [ -n "${wl_unit}" ]; then - guest_ssid=$(${NVRAM} get wl${wl_unit}.${guest_num}_ssid 2>/dev/null || echo "Guest Network") + guest_ssid=$(${NVRAM} get wl${wl_unit}.${guest_num}_ssid 2>/dev/null) + if [ -z "${guest_ssid}" ] || [ "${guest_ssid}" = " " ]; then + guest_ssid="Guest Network" + fi else guest_ssid="Guest Network" fi @@ -171,7 +176,6 @@ get_interface_info() { return fi - # Determine main interface type using detected mappings band=$(get_band_from_interface "${iface}") if [ -n "${band}" ]; then @@ -208,17 +212,14 @@ get_ip_from_mac() { local mac="$1" local ip="" - # Try /proc/net/arp first (more reliable) if [ -f /proc/net/arp ]; then ip=$(grep -i "${mac}" /proc/net/arp 2>/dev/null | awk '{print $1}' | head -n1) fi - # Fallback to arp command if [ -z "${ip}" ]; then ip=$(${ARP} -n 2>/dev/null | grep -i "${mac}" | awk '{print $1}' | head -n1) fi - # Return IP or Unknown if [ -z "${ip}" ] || [ "${ip}" = "?" ]; then echo "Unknown" else @@ -231,37 +232,32 @@ get_hostname() { local mac="$1" local ip="$2" local hostname="" - local mac_normalized=$(echo "${mac}" | tr 'A-F' 'a-f') + local mac_normalized="" + mac_normalized=$(echo "${mac}" | tr 'A-F' 'a-f') - # Try dnsmasq leases first - match by MAC if [ -f /var/lib/misc/dnsmasq.leases ]; then - hostname=$(awk -v mac="${mac_normalized}" 'tolower($2) == mac {print $4; exit}' /var/lib/misc/dnsmasq.leases 2>/dev/null) + hostname=$(awk -v mac="${mac_normalized}" '{if (tolower($2) == mac) {print $4; exit}}' /var/lib/misc/dnsmasq.leases 2>/dev/null) fi - # Try matching by IP in dnsmasq if MAC didn't work if [ -z "${hostname}" ] || [ "${hostname}" = "*" ]; then if [ -f /var/lib/misc/dnsmasq.leases ] && [ "${ip}" != "Unknown" ]; then - hostname=$(awk -v ip="${ip}" '$3 == ip {print $4; exit}' /var/lib/misc/dnsmasq.leases 2>/dev/null) + hostname=$(awk -v ip="${ip}" '{if ($3 == ip) {print $4; exit}}' /var/lib/misc/dnsmasq.leases 2>/dev/null) fi fi - # Try nvram custom_clientlist - format is MAC>IP if [ -z "${hostname}" ] || [ "${hostname}" = "*" ]; then local clientlist=$(${NVRAM} get custom_clientlist 2>/dev/null) if [ -n "${clientlist}" ]; then - # Parse custom_clientlist entries hostname=$(echo "${clientlist}" | tr '<' '\n' | grep -i "${mac}" | cut -d'>' -f1 | head -n1) fi fi - # Fallback to networkmap data if [ -z "${hostname}" ] || [ "${hostname}" = "*" ]; then if [ -f /var/lib/misc/networkmap.log ]; then hostname=$(grep -i "${mac}" /var/lib/misc/networkmap.log 2>/dev/null | awk '{print $1}' | head -n1) fi fi - # Last resort: use MAC address as identifier if [ -z "${hostname}" ] || [ "${hostname}" = "*" ]; then hostname="${mac}" fi @@ -276,8 +272,6 @@ get_hostname() { # Get wireless clients for a specific interface get_wireless_clients() { local iface="$1" - - # Use wl to get associated stations - extract MAC addresses ${WL} -i "${iface}" assoclist 2>/dev/null | awk '/assoclist/ {print $2}' } @@ -295,39 +289,84 @@ get_wireless_client_details() { local signal="0" local bandwidth="" - # Get IP from MAC address ip=$(get_ip_from_mac "${mac}") - - # Get hostname hostname=$(get_hostname "${mac}" "${ip}") - # Get wireless statistics using wl sta_info - if sta_info=$(${WL} -i "${iface}" sta_info "${mac}" 2>/dev/null); then - # Parse uptime (in seconds) + sta_info=$(${WL} -i "${iface}" sta_info "${mac}" 2>/dev/null) + if [ -n "${sta_info}" ]; then uptime=$(echo "${sta_info}" | grep 'in network' | awk '{for(i=1;i<=NF;i++){if($i=="network"){print $(i+1); exit}}}') [ -z "${uptime}" ] && uptime="0" - # Parse signal strength signal=$(echo "${sta_info}" | grep 'RSSI:' | head -n1 | awk '{print $2}') [ -z "${signal}" ] && signal="0" - # Parse rates (in Kbps, convert to Mbps) tx_rate=$(echo "${sta_info}" | grep 'rate of last tx pkt:' | awk '{print $6}') rx_rate=$(echo "${sta_info}" | grep 'rate of last rx pkt:' | awk '{print $6}') [ -z "${tx_rate}" ] && tx_rate="0" [ -z "${rx_rate}" ] && rx_rate="0" - # Parse bandwidth/channel width - bandwidth=$(echo "${sta_info}" | grep 'chanspec:' | head -n1 | awk '{for(i=1;i<=NF;i++){if($i=="chanspec:"){for(j=i+1;j<=NF;j++){if($j ~ /\)$/){print $(i+1); exit} else {printf "%s ", $(i+1); i++}}}}}') - [ -z "${bandwidth}" ] && bandwidth="Unknown" - fi - - # Get traffic statistics from /proc/net/nf_conntrack (approximation) - if [ "${ip}" != "Unknown" ] && [ -f /proc/net/nf_conntrack ]; then - tx_bytes=$(grep "${ip}" /proc/net/nf_conntrack 2>/dev/null | awk '{sum+=$1} END {print sum+0}') - rx_bytes=$(grep "${ip}" /proc/net/nf_conntrack 2>/dev/null | awk '{sum+=$2} END {print sum+0}') + # Get TX/RX bytes from wl sta_info + tx_bytes=$(echo "${sta_info}" | awk '/tx total bytes:/ {print $4}') + rx_bytes=$(echo "${sta_info}" | awk '/rx data bytes:/ {print $4}') [ -z "${tx_bytes}" ] && tx_bytes="0" [ -z "${rx_bytes}" ] && rx_bytes="0" + + local bw_mhz="" + local nss="" + + local link_bw_line=$(echo "${sta_info}" | grep -i 'link bandwidth') + if [ -n "${link_bw_line}" ]; then + bw_mhz=$(echo "${link_bw_line}" | grep -o '[0-9]\{2,3\}' | head -n1) + fi + + if [ -z "${bw_mhz}" ]; then + local chanspec_line=$(echo "${sta_info}" | grep 'chanspec') + if [ -n "${chanspec_line}" ]; then + # Extract bandwidth from chanspec (format: "100/160" where 160 is the bandwidth) + # Check if there's a / in the chanspec line + if echo "${chanspec_line}" | grep '/' >/dev/null 2>&1; then + bw_mhz=$(echo "${chanspec_line}" | sed 's/.*\/\([0-9]\{2,3\}\).*/\1/') + else + bw_mhz=$(echo "${chanspec_line}" | grep -o '[0-9]\{2,3\}' | tail -n1) + fi + fi + fi + + if [ -z "${bw_mhz}" ]; then + local omi_line=$(echo "${sta_info}" | grep 'OMI') + if [ -n "${omi_line}" ]; then + bw_mhz=$(echo "${omi_line}" | grep -o '[0-9]\{2,3\}[Mm][Hh][Zz]' | grep -o '[0-9]\{2,3\}') + fi + fi + + local omi_line=$(echo "${sta_info}" | grep 'OMI') + if [ -n "${omi_line}" ]; then + nss=$(echo "${omi_line}" | grep -o 'tx=[0-9]ss' | grep -o '[0-9]' | head -n1) + fi + + if [ -z "${nss}" ]; then + local nrate_line=$(echo "${sta_info}" | grep 'tx nrate\|rx nrate' | head -n1) + if [ -n "${nrate_line}" ]; then + nss=$(echo "${nrate_line}" | grep -o 'Nss [0-9]' | grep -o '[0-9]') + fi + fi + + if [ -z "${nss}" ]; then + local vht_line=$(echo "${sta_info}" | grep 'VHT SET' -A 1 | tail -n1) + if [ -n "${vht_line}" ]; then + nss=$(echo "${vht_line}" | grep -o '[0-9]x[0-9]' | head -n1 | cut -d'x' -f1) + fi + fi + + if [ -n "${bw_mhz}" ]; then + if [ -n "${nss}" ]; then + bandwidth="${nss}x${nss}:${bw_mhz}" + else + bandwidth="${bw_mhz}" + fi + else + bandwidth="Unknown" + fi fi # Format output @@ -348,13 +387,11 @@ get_wireless_client_details() { # LAN CLIENT ENUMERATION ################################################################################ -# Get LAN/br0 clients (non-wireless) get_lan_clients() { local wireless_macs="" local iface local temp_file="/tmp/lan_clients_$$.tmp" - # Collect all wireless MACs to exclude them for iface in $(get_wireless_interfaces); do local clients=$(get_wireless_clients "${iface}") if [ -n "${clients}" ]; then @@ -362,32 +399,24 @@ get_lan_clients() { fi done - # Normalize wireless MACs to lowercase wireless_macs=$(echo "${wireless_macs}" | tr 'A-F' 'a-f') - # Get all ARP entries from /proc/net/arp and store in temp file if [ -f /proc/net/arp ]; then ${CAT} /proc/net/arp | awk 'NR>1 && $3!="0x0" && $4!="00:00:00:00:00:00" {print $1, $4}' > "${temp_file}" else - # Fallback to arp command ${ARP} -n 2>/dev/null | awk 'NR>1 && $1!="?" {print $1, $3}' > "${temp_file}" fi - # Process ARP entries while read ip mac; do - # Skip empty lines [ -z "${mac}" ] || [ -z "${ip}" ] && continue [ "${ip}" = "IP" ] && continue - # Filter out non-local IP addresses if ! is_local_ip "${ip}"; then continue fi - # Normalize MAC to lowercase local mac_normalized=$(echo "${mac}" | tr 'A-F' 'a-f') - # Skip if MAC is in wireless list local is_wireless=0 for wmac in ${wireless_macs}; do if [ "${mac_normalized}" = "${wmac}" ]; then @@ -402,7 +431,93 @@ get_lan_clients() { fi done < "${temp_file}" | sort -u - # Clean up temp file + rm -f "${temp_file}" +} + +get_primary_subnet() { + local br0_ip=$(${IFCONFIG} br0 2>/dev/null | grep 'inet addr:' | awk '{print $2}' | cut -d':' -f2) + if [ -z "${br0_ip}" ]; then + br0_ip=$(${IFCONFIG} br0 2>/dev/null | awk '/inet / {print $2}') + fi + + if [ -n "${br0_ip}" ]; then + echo "${br0_ip}" | awk -F'.' '{print $1"."$2"."$3".0/24"}' + fi +} + +get_unique_subnets() { + local temp_file="/tmp/subnets_$$.tmp" + local primary_subnet=$(get_primary_subnet) + + if [ -f /proc/net/arp ]; then + ${CAT} /proc/net/arp | awk 'NR>1 && $3!="0x0" && $1!="0.0.0.0" {print $1}' > "${temp_file}" + else + ${ARP} -n 2>/dev/null | awk 'NR>1 && $1!="?" {print $1}' > "${temp_file}" + fi + + while read ip; do + if is_local_ip "${ip}"; then + local subnet=$(echo "${ip}" | awk -F'.' '{print $1"."$2"."$3".0/24"}') + if [ "${subnet}" != "${primary_subnet}" ]; then + echo "${subnet}" + fi + fi + done < "${temp_file}" | sort -u + + rm -f "${temp_file}" +} + +get_vlan_interface() { + local subnet="$1" + local subnet_prefix=$(echo "${subnet}" | cut -d'/' -f1 | sed 's/\.0$//') + + ${IFCONFIG} | grep "^br[0-9]\|^vlan[0-9]" | awk '{print $1}' | while read iface; do + local iface_ip=$(${IFCONFIG} "${iface}" 2>/dev/null | grep 'inet addr:' | awk '{print $2}' | cut -d':' -f2) + if [ -z "${iface_ip}" ]; then + iface_ip=$(${IFCONFIG} "${iface}" 2>/dev/null | awk '/inet / {print $2}') + fi + + if [ -n "${iface_ip}" ]; then + local iface_subnet=$(echo "${iface_ip}" | awk -F'.' '{print $1"."$2"."$3}') + if [ "${iface_subnet}" = "${subnet_prefix}" ]; then + echo "${iface}" + return + fi + fi + done +} + +get_vlan_clients() { + local subnet="$1" + local wireless_macs="$2" + local subnet_prefix=$(echo "${subnet}" | cut -d'/' -f1 | sed 's/\.0$//') + local temp_file="/tmp/vlan_clients_$$.tmp" + + if [ -f /proc/net/arp ]; then + ${CAT} /proc/net/arp | awk -v prefix="${subnet_prefix}" 'NR>1 && $3!="0x0" && $4!="00:00:00:00:00:00" && $1 ~ "^"prefix {print $1, $4}' > "${temp_file}" + else + ${ARP} -n 2>/dev/null | awk -v prefix="${subnet_prefix}" 'NR>1 && $1!="?" && $1 ~ "^"prefix {print $1, $3}' > "${temp_file}" + fi + + while read ip mac; do + [ -z "${mac}" ] || [ -z "${ip}" ] && continue + + local mac_normalized=$(echo "${mac}" | tr 'A-F' 'a-f') + + local is_wireless=0 + for wmac in ${wireless_macs}; do + if [ "${mac_normalized}" = "${wmac}" ]; then + is_wireless=1 + break + fi + done + + if [ ${is_wireless} -eq 0 ]; then + local hostname=$(get_hostname "${mac}" "${ip}") + printf " %-14s | %-15s | %s\n" "${hostname}" "${ip}" "${mac}" + fi + done < "${temp_file}" + rm -f "${temp_file}" } @@ -417,6 +532,7 @@ display_network_clients() { local band local guest_ssid local client_count + local wireless_macs="" echo "" echo "================================================================================" @@ -426,17 +542,14 @@ display_network_clients() { echo "================================================================================" echo "" - # Process each wireless interface for iface in $(get_wireless_interfaces); do info_str=$(get_interface_info "${iface}") iface_type=$(echo "${info_str}" | cut -d'|' -f1) band=$(echo "${info_str}" | cut -d'|' -f2) guest_ssid=$(echo "${info_str}" | cut -d'|' -f3) - # Skip unknown interfaces [ "${iface_type}" = "unknown" ] && continue - # Get clients for this interface client_count=0 client_list=$(get_wireless_clients "${iface}") @@ -444,19 +557,16 @@ display_network_clients() { client_count=$(echo "${client_list}" | wc -l) fi - # Display header based on interface type if [ "${iface_type}" = "guest" ]; then echo " Guest Wi-Fi: ${guest_ssid} - IFace: ${iface}" elif [ "${iface_type}" = "main" ]; then echo " Local ${band} - IFace: ${iface}" fi - # Display column headers for wireless if [ "${iface_type}" = "main" ] || [ "${iface_type}" = "guest" ]; then printf " %-14s | %-15s | %-17s | %7s | %5s | %5s | %7s | %7s | %3s | %s\n" \ "Name" "IP" "MAC" "Uptime" "TX GB" "RX GB" "TX Mbps" "RX Mbps" "Sig" "Band" - # Display clients if [ -n "${client_list}" ]; then for mac in ${client_list}; do get_wireless_client_details "${iface}" "${mac}" @@ -468,10 +578,63 @@ display_network_clients() { fi done - # Display LAN/br0 clients - echo " Local LAN/Non-VLAN AiMesh - IFace: br0" + for iface in $(get_wireless_interfaces); do + local clients=$(get_wireless_clients "${iface}") + if [ -n "${clients}" ]; then + wireless_macs="${wireless_macs} ${clients}" + fi + done + wireless_macs=$(echo "${wireless_macs}" | tr 'A-F' 'a-f') + + local primary_subnet=$(get_primary_subnet) + local vlan_subnets=$(get_unique_subnets) + local has_vlans=0 + + if [ -n "${vlan_subnets}" ]; then + has_vlans=1 + fi + + if [ ${has_vlans} -eq 1 ]; then + echo " Local VLAN/AiMesh VLAN" + echo "" + + for subnet in ${vlan_subnets}; do + local subnet_prefix=$(echo "${subnet}" | cut -d'/' -f1 | sed 's/\.0$//') + local vlan_iface=$(get_vlan_interface "${subnet}") + + if [ -n "${vlan_iface}" ]; then + echo " VLAN ${subnet} - IFace: ${vlan_iface}" + else + echo " VLAN ${subnet}" + fi + + printf " %-14s | %-15s | %s\n" "Name" "IP" "MAC" + + local vlan_clients=$(get_vlan_clients "${subnet}" "${wireless_macs}") + + if [ -n "${vlan_clients}" ]; then + echo "${vlan_clients}" + else + echo " No wired clients found" + fi + echo "" + done + fi + + echo " Local LAN/Non-VLAN AiMesh - Subnet: ${primary_subnet} - IFace: br0" printf " %-14s | %-15s | %s\n" "Name" "IP" "MAC" - get_lan_clients + + if [ -n "${primary_subnet}" ]; then + local primary_clients=$(get_vlan_clients "${primary_subnet}" "${wireless_macs}") + if [ -n "${primary_clients}" ]; then + echo "${primary_clients}" + else + echo " No wired clients found" + fi + else + get_lan_clients + fi + echo "" echo "================================================================================" } @@ -480,12 +643,8 @@ display_network_clients() { # ENTRY POINT ################################################################################ -clear - -# Detect router model and configure interface mappings detect_router_model -# Execute main routine display_network_clients exit 0 From ce73dfe4a98dc821dbe9facc73f2cec297e6b48f Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Wed, 10 Dec 2025 19:20:09 -0500 Subject: [PATCH 26/62] Update netmon-poc.sh --- netmon-poc.sh | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/netmon-poc.sh b/netmon-poc.sh index d8bb2b9..2d9c212 100644 --- a/netmon-poc.sh +++ b/netmon-poc.sh @@ -297,7 +297,8 @@ get_wireless_client_details() { uptime=$(echo "${sta_info}" | grep 'in network' | awk '{for(i=1;i<=NF;i++){if($i=="network"){print $(i+1); exit}}}') [ -z "${uptime}" ] && uptime="0" - signal=$(echo "${sta_info}" | grep 'RSSI:' | head -n1 | awk '{print $2}') + # Get signal strength from "smoothed rssi:" line + signal=$(echo "${sta_info}" | awk '/smoothed rssi:/ {print $3}') [ -z "${signal}" ] && signal="0" tx_rate=$(echo "${sta_info}" | grep 'rate of last tx pkt:' | awk '{print $6}') @@ -322,11 +323,8 @@ get_wireless_client_details() { if [ -z "${bw_mhz}" ]; then local chanspec_line=$(echo "${sta_info}" | grep 'chanspec') if [ -n "${chanspec_line}" ]; then - # Extract bandwidth from chanspec (format: "100/160" where 160 is the bandwidth) - # Check if there's a / in the chanspec line - if echo "${chanspec_line}" | grep '/' >/dev/null 2>&1; then - bw_mhz=$(echo "${chanspec_line}" | sed 's/.*\/\([0-9]\{2,3\}\).*/\1/') - else + bw_mhz=$(echo "${chanspec_line}" | sed 's/.*chanspec[^0-9]*[0-9]*\/\([0-9]*\).*/\1/') + if [ "${bw_mhz}" = "${chanspec_line}" ]; then bw_mhz=$(echo "${chanspec_line}" | grep -o '[0-9]\{2,3\}' | tail -n1) fi fi @@ -369,7 +367,13 @@ get_wireless_client_details() { fi fi - # Format output + if [ "${ip}" != "Unknown" ] && [ -f /proc/net/nf_conntrack ]; then + tx_bytes=$(grep "${ip}" /proc/net/nf_conntrack 2>/dev/null | awk '{sum+=$1} END {print sum+0}') + rx_bytes=$(grep "${ip}" /proc/net/nf_conntrack 2>/dev/null | awk '{sum+=$2} END {print sum+0}') + [ -z "${tx_bytes}" ] && tx_bytes="0" + [ -z "${rx_bytes}" ] && rx_bytes="0" + fi + printf " %-14s | %-15s | %-17s | %7s | %5s | %5s | %7.1f | %7.1f | %3s | %s\n" \ "${hostname}" \ "${ip}" \ From f89765ddb882d95d9b788af3b2485ca0561a5e3b Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Wed, 10 Dec 2025 19:31:25 -0500 Subject: [PATCH 27/62] Update netmon-poc.sh --- netmon-poc.sh | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/netmon-poc.sh b/netmon-poc.sh index 2d9c212..d63468a 100644 --- a/netmon-poc.sh +++ b/netmon-poc.sh @@ -297,8 +297,7 @@ get_wireless_client_details() { uptime=$(echo "${sta_info}" | grep 'in network' | awk '{for(i=1;i<=NF;i++){if($i=="network"){print $(i+1); exit}}}') [ -z "${uptime}" ] && uptime="0" - # Get signal strength from "smoothed rssi:" line - signal=$(echo "${sta_info}" | awk '/smoothed rssi:/ {print $3}') + signal=$(echo "${sta_info}" | grep 'RSSI:' | head -n1 | awk '{print $2}') [ -z "${signal}" ] && signal="0" tx_rate=$(echo "${sta_info}" | grep 'rate of last tx pkt:' | awk '{print $6}') @@ -307,8 +306,8 @@ get_wireless_client_details() { [ -z "${rx_rate}" ] && rx_rate="0" # Get TX/RX bytes from wl sta_info - tx_bytes=$(echo "${sta_info}" | awk '/tx total bytes:/ {print $4}') - rx_bytes=$(echo "${sta_info}" | awk '/rx data bytes:/ {print $4}') + tx_bytes=$(echo "${sta_info}" | awk '/tx total bytes/ {print $NF}') + rx_bytes=$(echo "${sta_info}" | awk '/rx data bytes/ {print $NF}') [ -z "${tx_bytes}" ] && tx_bytes="0" [ -z "${rx_bytes}" ] && rx_bytes="0" @@ -323,8 +322,11 @@ get_wireless_client_details() { if [ -z "${bw_mhz}" ]; then local chanspec_line=$(echo "${sta_info}" | grep 'chanspec') if [ -n "${chanspec_line}" ]; then - bw_mhz=$(echo "${chanspec_line}" | sed 's/.*chanspec[^0-9]*[0-9]*\/\([0-9]*\).*/\1/') - if [ "${bw_mhz}" = "${chanspec_line}" ]; then + # Extract bandwidth from chanspec (format: "100/160" where 160 is the bandwidth) + # Check if there's a / in the chanspec line + if echo "${chanspec_line}" | grep '/' >/dev/null 2>&1; then + bw_mhz=$(echo "${chanspec_line}" | sed 's/.*\/\([0-9]\{2,3\}\).*/\1/') + else bw_mhz=$(echo "${chanspec_line}" | grep -o '[0-9]\{2,3\}' | tail -n1) fi fi @@ -367,13 +369,7 @@ get_wireless_client_details() { fi fi - if [ "${ip}" != "Unknown" ] && [ -f /proc/net/nf_conntrack ]; then - tx_bytes=$(grep "${ip}" /proc/net/nf_conntrack 2>/dev/null | awk '{sum+=$1} END {print sum+0}') - rx_bytes=$(grep "${ip}" /proc/net/nf_conntrack 2>/dev/null | awk '{sum+=$2} END {print sum+0}') - [ -z "${tx_bytes}" ] && tx_bytes="0" - [ -z "${rx_bytes}" ] && rx_bytes="0" - fi - + # Format output printf " %-14s | %-15s | %-17s | %7s | %5s | %5s | %7.1f | %7.1f | %3s | %s\n" \ "${hostname}" \ "${ip}" \ From ab0b383bcfa82ed073b27d009d8d9e48553de16a Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Wed, 10 Dec 2025 20:06:52 -0500 Subject: [PATCH 28/62] Update netmon-poc.sh --- netmon-poc.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/netmon-poc.sh b/netmon-poc.sh index d63468a..c54cb11 100644 --- a/netmon-poc.sh +++ b/netmon-poc.sh @@ -297,7 +297,7 @@ get_wireless_client_details() { uptime=$(echo "${sta_info}" | grep 'in network' | awk '{for(i=1;i<=NF;i++){if($i=="network"){print $(i+1); exit}}}') [ -z "${uptime}" ] && uptime="0" - signal=$(echo "${sta_info}" | grep 'RSSI:' | head -n1 | awk '{print $2}') + signal=$(echo "${sta_info}" | grep 'smoothed rssi:' | head -n1 | awk '{print $3}') [ -z "${signal}" ] && signal="0" tx_rate=$(echo "${sta_info}" | grep 'rate of last tx pkt:' | awk '{print $6}') @@ -306,8 +306,8 @@ get_wireless_client_details() { [ -z "${rx_rate}" ] && rx_rate="0" # Get TX/RX bytes from wl sta_info - tx_bytes=$(echo "${sta_info}" | awk '/tx total bytes/ {print $NF}') - rx_bytes=$(echo "${sta_info}" | awk '/rx data bytes/ {print $NF}') + tx_bytes=$(echo "${sta_info}" | awk '/tx total bytes:/ {print $4}') + rx_bytes=$(echo "${sta_info}" | awk '/rx data bytes:/ {print $4}') [ -z "${tx_bytes}" ] && tx_bytes="0" [ -z "${rx_bytes}" ] && rx_bytes="0" From b2cd07c659b76361f7266db75427e45cf8ca25e7 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Wed, 10 Dec 2025 20:47:45 -0500 Subject: [PATCH 29/62] Update netmon-poc.sh --- netmon-poc.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netmon-poc.sh b/netmon-poc.sh index c54cb11..ae3e8a9 100644 --- a/netmon-poc.sh +++ b/netmon-poc.sh @@ -46,7 +46,7 @@ detect_router_model() { ;; # Four-band routers: 5GHz, 6GHz, 6GHz, 2.4GHz (wl0=5, wl1=6, wl2=6, wl3=2.4) - GT-BE98_Pro) + GT-BE98_PRO) IFNAME_5=$(${NVRAM} get wl0_ifname 2>/dev/null) IFNAME_6=$(${NVRAM} get wl1_ifname 2>/dev/null) IFNAME_6_2=$(${NVRAM} get wl2_ifname 2>/dev/null) @@ -61,7 +61,7 @@ detect_router_model() { ;; # Three-band routers: 2.4GHz, 5GHz, 5GHz (wl0=2.4, wl1=5, wl2=5) - GT-AX11000_Pro|GT-AX11000|ZenWiFi_Pro_XT12|ZenWiFi_XT8) + GT-AX11000_PRO|GT-AX11000|ZenWiFi_Pro_XT12|ZenWiFi_XT8) IFNAME_24=$(${NVRAM} get wl0_ifname 2>/dev/null) IFNAME_5=$(${NVRAM} get wl1_ifname 2>/dev/null) IFNAME_5_2=$(${NVRAM} get wl2_ifname 2>/dev/null) From 1e7f5b5a26b64341407620a206581092ea6fd12c Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Wed, 10 Dec 2025 21:10:25 -0500 Subject: [PATCH 30/62] Update netmon-poc.sh --- netmon-poc.sh | 180 +++++++++++++++++++++++++------------------------- 1 file changed, 91 insertions(+), 89 deletions(-) diff --git a/netmon-poc.sh b/netmon-poc.sh index ae3e8a9..c345a76 100644 --- a/netmon-poc.sh +++ b/netmon-poc.sh @@ -32,9 +32,9 @@ IFNAME_6_2="" detect_router_model() { local router_model=$(${NVRAM} get productid 2>/dev/null) [ -z "${router_model}" ] && router_model=$(${NVRAM} get model 2>/dev/null) - + echo "Detected Router Model: ${router_model}" >&2 - + # Determine radio configuration based on router model case "${router_model}" in # Four-band routers: 5GHz, 5GHz, 6GHz, 2.4GHz (wl0=5, wl1=5, wl2=6, wl3=2.4) @@ -44,7 +44,7 @@ detect_router_model() { IFNAME_6=$(${NVRAM} get wl2_ifname 2>/dev/null) IFNAME_24=$(${NVRAM} get wl3_ifname 2>/dev/null) ;; - + # Four-band routers: 5GHz, 6GHz, 6GHz, 2.4GHz (wl0=5, wl1=6, wl2=6, wl3=2.4) GT-BE98_PRO) IFNAME_5=$(${NVRAM} get wl0_ifname 2>/dev/null) @@ -52,28 +52,28 @@ detect_router_model() { IFNAME_6_2=$(${NVRAM} get wl2_ifname 2>/dev/null) IFNAME_24=$(${NVRAM} get wl3_ifname 2>/dev/null) ;; - + # Three-band routers: 2.4GHz, 5GHz, 6GHz (wl0=2.4, wl1=5, wl2=6) GT-AXE11000|ZenWiFi_ET8|RT-BE96U|RT-BE92U) IFNAME_24=$(${NVRAM} get wl0_ifname 2>/dev/null) IFNAME_5=$(${NVRAM} get wl1_ifname 2>/dev/null) IFNAME_6=$(${NVRAM} get wl2_ifname 2>/dev/null) ;; - + # Three-band routers: 2.4GHz, 5GHz, 5GHz (wl0=2.4, wl1=5, wl2=5) GT-AX11000_PRO|GT-AX11000|ZenWiFi_Pro_XT12|ZenWiFi_XT8) IFNAME_24=$(${NVRAM} get wl0_ifname 2>/dev/null) IFNAME_5=$(${NVRAM} get wl1_ifname 2>/dev/null) IFNAME_5_2=$(${NVRAM} get wl2_ifname 2>/dev/null) ;; - + # Default two-band routers: 2.4GHz, 5GHz (wl0=2.4, wl1=5) *) IFNAME_24=$(${NVRAM} get wl0_ifname 2>/dev/null) IFNAME_5=$(${NVRAM} get wl1_ifname 2>/dev/null) ;; esac - + # Log detected interfaces echo "Interface Mapping:" >&2 [ -n "${IFNAME_24}" ] && echo " 2.4GHz: ${IFNAME_24}" >&2 @@ -90,7 +90,7 @@ detect_router_model() { # Check if IP is a local/private address is_local_ip() { local ip="$1" - + # Check for private IP ranges case "${ip}" in 10.*) return 0 ;; @@ -116,7 +116,7 @@ get_wireless_interfaces() { # Get band name from interface name based on detected configuration get_band_from_interface() { local iface="$1" - + if [ "${iface}" = "${IFNAME_24}" ]; then echo "2.4GHz" elif [ "${iface}" = "${IFNAME_5}" ]; then @@ -138,16 +138,16 @@ get_interface_info() { local band="" local type="" local guest_ssid="" - + echo "${iface}" | grep '\.' >/dev/null 2>&1 if [ $? -eq 0 ]; then local base_iface=$(echo "${iface}" | cut -d'.' -f1) local guest_num=$(echo "${iface}" | cut -d'.' -f2) - + band=$(get_band_from_interface "${base_iface}") - + local wl_unit="" - + echo "${base_iface}" | grep '^wl[0-9]$' >/dev/null 2>&1 if [ $? -eq 0 ]; then wl_unit=$(echo "${base_iface}" | grep -o '[0-9]') @@ -161,7 +161,7 @@ get_interface_info() { fi done fi - + if [ -n "${wl_unit}" ]; then guest_ssid=$(${NVRAM} get wl${wl_unit}.${guest_num}_ssid 2>/dev/null) if [ -z "${guest_ssid}" ] || [ "${guest_ssid}" = " " ]; then @@ -170,14 +170,14 @@ get_interface_info() { else guest_ssid="Guest Network" fi - + type="guest" echo "${type}|${band}|${guest_ssid}" return fi - + band=$(get_band_from_interface "${iface}") - + if [ -n "${band}" ]; then type="main" elif [ "${iface}" = "br0" ]; then @@ -185,7 +185,7 @@ get_interface_info() { else type="unknown" fi - + echo "${type}|${band}|" } @@ -211,15 +211,15 @@ bytes_to_gb() { get_ip_from_mac() { local mac="$1" local ip="" - + if [ -f /proc/net/arp ]; then ip=$(grep -i "${mac}" /proc/net/arp 2>/dev/null | awk '{print $1}' | head -n1) fi - + if [ -z "${ip}" ]; then ip=$(${ARP} -n 2>/dev/null | grep -i "${mac}" | awk '{print $1}' | head -n1) fi - + if [ -z "${ip}" ] || [ "${ip}" = "?" ]; then echo "Unknown" else @@ -234,34 +234,36 @@ get_hostname() { local hostname="" local mac_normalized="" mac_normalized=$(echo "${mac}" | tr 'A-F' 'a-f') - - if [ -f /var/lib/misc/dnsmasq.leases ]; then - hostname=$(awk -v mac="${mac_normalized}" '{if (tolower($2) == mac) {print $4; exit}}' /var/lib/misc/dnsmasq.leases 2>/dev/null) + + if [ -z "${hostname}" ] || [ "${hostname}" = "*" ]; then + local clientlist=$(${NVRAM} get custom_clientlist 2>/dev/null) + if [ -n "${clientlist}" ]; then + hostname=$(echo "${clientlist}" | tr '<' '\n' | grep -i "${mac}" | cut -d'>' -f1 | head -n1) + fi fi - + if [ -z "${hostname}" ] || [ "${hostname}" = "*" ]; then - if [ -f /var/lib/misc/dnsmasq.leases ] && [ "${ip}" != "Unknown" ]; then - hostname=$(awk -v ip="${ip}" '{if ($3 == ip) {print $4; exit}}' /var/lib/misc/dnsmasq.leases 2>/dev/null) + if [ -f /var/lib/misc/dnsmasq.leases ]; then + hostname=$(awk -v mac="${mac_normalized}" '{if (tolower($2) == mac) {print $4; exit}}' /var/lib/misc/dnsmasq.leases 2>/dev/null) fi fi - + if [ -z "${hostname}" ] || [ "${hostname}" = "*" ]; then - local clientlist=$(${NVRAM} get custom_clientlist 2>/dev/null) - if [ -n "${clientlist}" ]; then - hostname=$(echo "${clientlist}" | tr '<' '\n' | grep -i "${mac}" | cut -d'>' -f1 | head -n1) + if [ -f /var/lib/misc/dnsmasq.leases ] && [ "${ip}" != "Unknown" ]; then + hostname=$(awk -v ip="${ip}" '{if ($3 == ip) {print $4; exit}}' /var/lib/misc/dnsmasq.leases 2>/dev/null) fi fi - + if [ -z "${hostname}" ] || [ "${hostname}" = "*" ]; then if [ -f /var/lib/misc/networkmap.log ]; then hostname=$(grep -i "${mac}" /var/lib/misc/networkmap.log 2>/dev/null | awk '{print $1}' | head -n1) fi fi - + if [ -z "${hostname}" ] || [ "${hostname}" = "*" ]; then hostname="${mac}" fi - + echo "${hostname}" } @@ -288,37 +290,37 @@ get_wireless_client_details() { local rx_rate="0" local signal="0" local bandwidth="" - + ip=$(get_ip_from_mac "${mac}") hostname=$(get_hostname "${mac}" "${ip}") - + sta_info=$(${WL} -i "${iface}" sta_info "${mac}" 2>/dev/null) if [ -n "${sta_info}" ]; then uptime=$(echo "${sta_info}" | grep 'in network' | awk '{for(i=1;i<=NF;i++){if($i=="network"){print $(i+1); exit}}}') [ -z "${uptime}" ] && uptime="0" - + signal=$(echo "${sta_info}" | grep 'smoothed rssi:' | head -n1 | awk '{print $3}') [ -z "${signal}" ] && signal="0" - + tx_rate=$(echo "${sta_info}" | grep 'rate of last tx pkt:' | awk '{print $6}') rx_rate=$(echo "${sta_info}" | grep 'rate of last rx pkt:' | awk '{print $6}') [ -z "${tx_rate}" ] && tx_rate="0" [ -z "${rx_rate}" ] && rx_rate="0" - + # Get TX/RX bytes from wl sta_info tx_bytes=$(echo "${sta_info}" | awk '/tx total bytes:/ {print $4}') rx_bytes=$(echo "${sta_info}" | awk '/rx data bytes:/ {print $4}') [ -z "${tx_bytes}" ] && tx_bytes="0" [ -z "${rx_bytes}" ] && rx_bytes="0" - + local bw_mhz="" local nss="" - + local link_bw_line=$(echo "${sta_info}" | grep -i 'link bandwidth') if [ -n "${link_bw_line}" ]; then bw_mhz=$(echo "${link_bw_line}" | grep -o '[0-9]\{2,3\}' | head -n1) fi - + if [ -z "${bw_mhz}" ]; then local chanspec_line=$(echo "${sta_info}" | grep 'chanspec') if [ -n "${chanspec_line}" ]; then @@ -331,33 +333,33 @@ get_wireless_client_details() { fi fi fi - + if [ -z "${bw_mhz}" ]; then local omi_line=$(echo "${sta_info}" | grep 'OMI') if [ -n "${omi_line}" ]; then bw_mhz=$(echo "${omi_line}" | grep -o '[0-9]\{2,3\}[Mm][Hh][Zz]' | grep -o '[0-9]\{2,3\}') fi fi - + local omi_line=$(echo "${sta_info}" | grep 'OMI') if [ -n "${omi_line}" ]; then nss=$(echo "${omi_line}" | grep -o 'tx=[0-9]ss' | grep -o '[0-9]' | head -n1) fi - + if [ -z "${nss}" ]; then local nrate_line=$(echo "${sta_info}" | grep 'tx nrate\|rx nrate' | head -n1) if [ -n "${nrate_line}" ]; then nss=$(echo "${nrate_line}" | grep -o 'Nss [0-9]' | grep -o '[0-9]') fi fi - + if [ -z "${nss}" ]; then local vht_line=$(echo "${sta_info}" | grep 'VHT SET' -A 1 | tail -n1) if [ -n "${vht_line}" ]; then nss=$(echo "${vht_line}" | grep -o '[0-9]x[0-9]' | head -n1 | cut -d'x' -f1) fi fi - + if [ -n "${bw_mhz}" ]; then if [ -n "${nss}" ]; then bandwidth="${nss}x${nss}:${bw_mhz}" @@ -368,7 +370,7 @@ get_wireless_client_details() { bandwidth="Unknown" fi fi - + # Format output printf " %-14s | %-15s | %-17s | %7s | %5s | %5s | %7.1f | %7.1f | %3s | %s\n" \ "${hostname}" \ @@ -391,32 +393,32 @@ get_lan_clients() { local wireless_macs="" local iface local temp_file="/tmp/lan_clients_$$.tmp" - + for iface in $(get_wireless_interfaces); do local clients=$(get_wireless_clients "${iface}") if [ -n "${clients}" ]; then wireless_macs="${wireless_macs} ${clients}" fi done - + wireless_macs=$(echo "${wireless_macs}" | tr 'A-F' 'a-f') - + if [ -f /proc/net/arp ]; then ${CAT} /proc/net/arp | awk 'NR>1 && $3!="0x0" && $4!="00:00:00:00:00:00" {print $1, $4}' > "${temp_file}" else ${ARP} -n 2>/dev/null | awk 'NR>1 && $1!="?" {print $1, $3}' > "${temp_file}" fi - + while read ip mac; do [ -z "${mac}" ] || [ -z "${ip}" ] && continue [ "${ip}" = "IP" ] && continue - + if ! is_local_ip "${ip}"; then continue fi - + local mac_normalized=$(echo "${mac}" | tr 'A-F' 'a-f') - + local is_wireless=0 for wmac in ${wireless_macs}; do if [ "${mac_normalized}" = "${wmac}" ]; then @@ -424,13 +426,13 @@ get_lan_clients() { break fi done - + if [ ${is_wireless} -eq 0 ]; then local hostname=$(get_hostname "${mac}" "${ip}") printf " %-14s | %-15s | %s\n" "${hostname}" "${ip}" "${mac}" fi done < "${temp_file}" | sort -u - + rm -f "${temp_file}" } @@ -439,7 +441,7 @@ get_primary_subnet() { if [ -z "${br0_ip}" ]; then br0_ip=$(${IFCONFIG} br0 2>/dev/null | awk '/inet / {print $2}') fi - + if [ -n "${br0_ip}" ]; then echo "${br0_ip}" | awk -F'.' '{print $1"."$2"."$3".0/24"}' fi @@ -448,13 +450,13 @@ get_primary_subnet() { get_unique_subnets() { local temp_file="/tmp/subnets_$$.tmp" local primary_subnet=$(get_primary_subnet) - + if [ -f /proc/net/arp ]; then ${CAT} /proc/net/arp | awk 'NR>1 && $3!="0x0" && $1!="0.0.0.0" {print $1}' > "${temp_file}" else ${ARP} -n 2>/dev/null | awk 'NR>1 && $1!="?" {print $1}' > "${temp_file}" fi - + while read ip; do if is_local_ip "${ip}"; then local subnet=$(echo "${ip}" | awk -F'.' '{print $1"."$2"."$3".0/24"}') @@ -463,20 +465,20 @@ get_unique_subnets() { fi fi done < "${temp_file}" | sort -u - + rm -f "${temp_file}" } get_vlan_interface() { local subnet="$1" local subnet_prefix=$(echo "${subnet}" | cut -d'/' -f1 | sed 's/\.0$//') - + ${IFCONFIG} | grep "^br[0-9]\|^vlan[0-9]" | awk '{print $1}' | while read iface; do local iface_ip=$(${IFCONFIG} "${iface}" 2>/dev/null | grep 'inet addr:' | awk '{print $2}' | cut -d':' -f2) if [ -z "${iface_ip}" ]; then iface_ip=$(${IFCONFIG} "${iface}" 2>/dev/null | awk '/inet / {print $2}') fi - + if [ -n "${iface_ip}" ]; then local iface_subnet=$(echo "${iface_ip}" | awk -F'.' '{print $1"."$2"."$3}') if [ "${iface_subnet}" = "${subnet_prefix}" ]; then @@ -492,18 +494,18 @@ get_vlan_clients() { local wireless_macs="$2" local subnet_prefix=$(echo "${subnet}" | cut -d'/' -f1 | sed 's/\.0$//') local temp_file="/tmp/vlan_clients_$$.tmp" - + if [ -f /proc/net/arp ]; then ${CAT} /proc/net/arp | awk -v prefix="${subnet_prefix}" 'NR>1 && $3!="0x0" && $4!="00:00:00:00:00:00" && $1 ~ "^"prefix {print $1, $4}' > "${temp_file}" else ${ARP} -n 2>/dev/null | awk -v prefix="${subnet_prefix}" 'NR>1 && $1!="?" && $1 ~ "^"prefix {print $1, $3}' > "${temp_file}" fi - + while read ip mac; do [ -z "${mac}" ] || [ -z "${ip}" ] && continue - + local mac_normalized=$(echo "${mac}" | tr 'A-F' 'a-f') - + local is_wireless=0 for wmac in ${wireless_macs}; do if [ "${mac_normalized}" = "${wmac}" ]; then @@ -511,13 +513,13 @@ get_vlan_clients() { break fi done - + if [ ${is_wireless} -eq 0 ]; then local hostname=$(get_hostname "${mac}" "${ip}") printf " %-14s | %-15s | %s\n" "${hostname}" "${ip}" "${mac}" fi done < "${temp_file}" - + rm -f "${temp_file}" } @@ -533,7 +535,7 @@ display_network_clients() { local guest_ssid local client_count local wireless_macs="" - + echo "" echo "================================================================================" echo " ASUS Network Client Monitor" @@ -541,32 +543,32 @@ display_network_clients() { echo " Generated: $(date '+%Y-%m-%d %H:%M:%S')" echo "================================================================================" echo "" - + for iface in $(get_wireless_interfaces); do info_str=$(get_interface_info "${iface}") iface_type=$(echo "${info_str}" | cut -d'|' -f1) band=$(echo "${info_str}" | cut -d'|' -f2) guest_ssid=$(echo "${info_str}" | cut -d'|' -f3) - + [ "${iface_type}" = "unknown" ] && continue - + client_count=0 client_list=$(get_wireless_clients "${iface}") - + if [ -n "${client_list}" ]; then client_count=$(echo "${client_list}" | wc -l) fi - + if [ "${iface_type}" = "guest" ]; then echo " Guest Wi-Fi: ${guest_ssid} - IFace: ${iface}" elif [ "${iface_type}" = "main" ]; then echo " Local ${band} - IFace: ${iface}" fi - + if [ "${iface_type}" = "main" ] || [ "${iface_type}" = "guest" ]; then printf " %-14s | %-15s | %-17s | %7s | %5s | %5s | %7s | %7s | %3s | %s\n" \ "Name" "IP" "MAC" "Uptime" "TX GB" "RX GB" "TX Mbps" "RX Mbps" "Sig" "Band" - + if [ -n "${client_list}" ]; then for mac in ${client_list}; do get_wireless_client_details "${iface}" "${mac}" @@ -577,7 +579,7 @@ display_network_clients() { echo "" fi done - + for iface in $(get_wireless_interfaces); do local clients=$(get_wireless_clients "${iface}") if [ -n "${clients}" ]; then @@ -585,33 +587,33 @@ display_network_clients() { fi done wireless_macs=$(echo "${wireless_macs}" | tr 'A-F' 'a-f') - + local primary_subnet=$(get_primary_subnet) local vlan_subnets=$(get_unique_subnets) local has_vlans=0 - + if [ -n "${vlan_subnets}" ]; then has_vlans=1 fi - + if [ ${has_vlans} -eq 1 ]; then echo " Local VLAN/AiMesh VLAN" echo "" - + for subnet in ${vlan_subnets}; do local subnet_prefix=$(echo "${subnet}" | cut -d'/' -f1 | sed 's/\.0$//') local vlan_iface=$(get_vlan_interface "${subnet}") - + if [ -n "${vlan_iface}" ]; then echo " VLAN ${subnet} - IFace: ${vlan_iface}" else echo " VLAN ${subnet}" fi - + printf " %-14s | %-15s | %s\n" "Name" "IP" "MAC" - + local vlan_clients=$(get_vlan_clients "${subnet}" "${wireless_macs}") - + if [ -n "${vlan_clients}" ]; then echo "${vlan_clients}" else @@ -620,10 +622,10 @@ display_network_clients() { echo "" done fi - + echo " Local LAN/Non-VLAN AiMesh - Subnet: ${primary_subnet} - IFace: br0" printf " %-14s | %-15s | %s\n" "Name" "IP" "MAC" - + if [ -n "${primary_subnet}" ]; then local primary_clients=$(get_vlan_clients "${primary_subnet}" "${wireless_macs}") if [ -n "${primary_clients}" ]; then @@ -634,7 +636,7 @@ display_network_clients() { else get_lan_clients fi - + echo "" echo "================================================================================" } From 9b2cdfa5fe24717568c4c2ab6096822c22887bf4 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Thu, 11 Dec 2025 21:02:28 -0500 Subject: [PATCH 31/62] Refactor MAC address handling and hostname retrieval Normalized MAC address handling and updated hostname retrieval logic. Commented out redundant hostname lookup from networkmap.log. --- netmon-poc.sh | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/netmon-poc.sh b/netmon-poc.sh index c345a76..d119bff 100644 --- a/netmon-poc.sh +++ b/netmon-poc.sh @@ -211,11 +211,19 @@ bytes_to_gb() { get_ip_from_mac() { local mac="$1" local ip="" + local mac_normalized="" + mac_normalized=$(echo "${mac}" | tr 'A-F' 'a-f') if [ -f /proc/net/arp ]; then ip=$(grep -i "${mac}" /proc/net/arp 2>/dev/null | awk '{print $1}' | head -n1) fi + if [ -z "${ip}" ]; then + if [ -f /var/lib/misc/dnsmasq.leases ]; then + ip=$(awk -v mac="${mac_normalized}" '{if (tolower($2) == mac) {print $3; exit}}' /var/lib/misc/dnsmasq.leases 2>/dev/null) + fi + fi + if [ -z "${ip}" ]; then ip=$(${ARP} -n 2>/dev/null | grep -i "${mac}" | awk '{print $1}' | head -n1) fi @@ -254,11 +262,11 @@ get_hostname() { fi fi - if [ -z "${hostname}" ] || [ "${hostname}" = "*" ]; then - if [ -f /var/lib/misc/networkmap.log ]; then - hostname=$(grep -i "${mac}" /var/lib/misc/networkmap.log 2>/dev/null | awk '{print $1}' | head -n1) - fi - fi + #if [ -z "${hostname}" ] || [ "${hostname}" = "*" ]; then + # if [ -f /var/lib/misc/networkmap.log ]; then + # hostname=$(grep -i "${mac}" /var/lib/misc/networkmap.log 2>/dev/null | awk '{print $1}' | head -n1) + # fi + #fi if [ -z "${hostname}" ] || [ "${hostname}" = "*" ]; then hostname="${mac}" From a8f20be3645904be9247b2211596a6fd659baa4b Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Thu, 11 Dec 2025 21:31:32 -0500 Subject: [PATCH 32/62] Clean up unused hostname resolution code Removed commented-out code for hostname resolution. --- netmon-poc.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/netmon-poc.sh b/netmon-poc.sh index d119bff..1917a5c 100644 --- a/netmon-poc.sh +++ b/netmon-poc.sh @@ -262,12 +262,6 @@ get_hostname() { fi fi - #if [ -z "${hostname}" ] || [ "${hostname}" = "*" ]; then - # if [ -f /var/lib/misc/networkmap.log ]; then - # hostname=$(grep -i "${mac}" /var/lib/misc/networkmap.log 2>/dev/null | awk '{print $1}' | head -n1) - # fi - #fi - if [ -z "${hostname}" ] || [ "${hostname}" = "*" ]; then hostname="${mac}" fi From b612947b9e2c91569d7a8431cbc60d67c559cf19 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Sat, 13 Dec 2025 10:48:35 -0500 Subject: [PATCH 33/62] Incorporated all of @ExtremeFiretop's suggestions --- netmon-poc.sh | 745 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 525 insertions(+), 220 deletions(-) diff --git a/netmon-poc.sh b/netmon-poc.sh index 1917a5c..aa17d84 100644 --- a/netmon-poc.sh +++ b/netmon-poc.sh @@ -17,6 +17,10 @@ ARP="arp" IFCONFIG="ifconfig" CAT="cat" +# Temporary files for client tracking and deduplication +PROCESSED_CLIENTS="/tmp/netmon_processed_clients_$$.txt" +PROCESSED_VLAN_CLIENTS="/tmp/netmon_processed_vlan_clients_$$.txt" + # Radio configuration variables IFNAME_24="" IFNAME_5="" @@ -83,10 +87,74 @@ detect_router_model() { [ -n "${IFNAME_6_2}" ] && echo " 6.0GHz-2: ${IFNAME_6_2}" >&2 } +################################################################################ +# MLO/MLD AWARENESS FUNCTIONS +################################################################################ + +# Read all DHCP lease files including merged leases for MLO/MLD support +read_all_dhcp_leases() { + # Include the merged lease file if it exists (for MLO/MLD clients) + local lease_files="/var/lib/misc/dnsmasq-*.leases /var/lib/misc/dnsmasq.leases" + if [ -f "/tmp/dnsmasq-merged.leases" ]; then + lease_files="${lease_files} /tmp/dnsmasq-merged.leases" + fi + local all_leases="" + all_leases=$(${CAT} ${lease_files} 2>/dev/null) + echo "${all_leases}" +} + +# Unified MLD MAC retrieval logic: given the current dhcpleases and association MAC (in lowercase), +# determine the lookup MAC (which may be the MLD MAC if present). +# For WiFi 7 / MLO clients the MAC used by 'wl assoclist' may NOT be the same MAC +# that appears in ARP/DHCP. This function finds the correct MAC to use for lookups. +get_lookup_mac() { + local maclower="$1" + local leases="$2" + local lookup_mac="${maclower}" + local mld_line="" + local field_count="" + local mld_mac="" + + mld_line=$(echo "${leases}" | grep -i "${maclower}" | head -n1) + if [ -n "${mld_line}" ]; then + field_count=$(echo "${mld_line}" | awk '{print NF; exit}') + if [ "${field_count}" -ge 5 ]; then + mld_mac=$(echo "${mld_line}" | awk '{print $5; exit}') + if [ -n "${mld_mac}" ] && [ "${mld_mac}" != "*" ]; then + lookup_mac=$(echo "${mld_mac}" | awk '{print tolower($0)}') + fi + fi + fi + echo "${lookup_mac}" +} + ################################################################################ # UTILITY FUNCTIONS ################################################################################ +# Get the bridge name that an interface is enslaved to +get_bridge_for_interface() { + local iface="$1" + local bridge_name="" + + for br in $(ls /sys/class/net 2>/dev/null | grep '^br'); do + if [ -d "/sys/class/net/${br}/brif/${iface}" ]; then + bridge_name="${br}" + break + fi + done + + echo "${bridge_name}" +} + +# Get list of VLAN/AiMesh bridge interfaces from apg_ifnames +get_vlan_bridges() { + local apg_ifnames=$(${NVRAM} get apg_ifnames 2>/dev/null) + if [ -n "${apg_ifnames}" ]; then + echo "${apg_ifnames}" + fi +} + # Check if IP is a local/private address is_local_ip() { local ip="$1" @@ -104,13 +172,37 @@ is_local_ip() { esac } -# Get all active wireless interfaces +# Get all active wireless interfaces including VIFs (guest networks) get_wireless_interfaces() { + local temp_file="/tmp/wireless_ifaces_$$.tmp" + + # Get main wireless interfaces ${IFCONFIG} | grep '^eth[0-9]\|^wl[0-9]' | awk '{print $1}' | while read iface; do if ${WL} -i "${iface}" status >/dev/null 2>&1; then echo "${iface}" fi - done | sort -u + done > "${temp_file}" + + # Get VIFs (virtual interfaces for guest networks) from nvram + for wl_unit in 0 1 2 3; do + local vifs=$(${NVRAM} get wl${wl_unit}_vifs 2>/dev/null) + if [ -n "${vifs}" ]; then + for vif in ${vifs}; do + # Check if VIF has an SSID configured (indicates it's active) + local vif_ssid=$(${NVRAM} get ${vif}_ssid 2>/dev/null) + if [ -n "${vif_ssid}" ] && [ "${vif_ssid}" != " " ]; then + # Verify the interface exists and is up + if ${IFCONFIG} "${vif}" >/dev/null 2>&1; then + echo "${vif}" + fi + fi + done + fi + done >> "${temp_file}" + + # Sort and deduplicate + sort -u "${temp_file}" + rm -f "${temp_file}" } # Get band name from interface name based on detected configuration @@ -133,49 +225,60 @@ get_band_from_interface() { } # Get interface type and band information +# Uses bridge membership to accurately determine guest vs local Wi-Fi get_interface_info() { local iface="$1" local band="" local type="" local guest_ssid="" + local bridge_name="" + + # Check if this is a guest/VIF interface by looking for it in bridge interfaces + # Find which bridge this interface is enslaved to + for br in $(ls /sys/class/net 2>/dev/null | grep '^br'); do + if [ -d "/sys/class/net/${br}/brif/${iface}" ]; then + bridge_name="${br}" + break + fi + done - echo "${iface}" | grep '\.' >/dev/null 2>&1 - if [ $? -eq 0 ]; then - local base_iface=$(echo "${iface}" | cut -d'.' -f1) - local guest_num=$(echo "${iface}" | cut -d'.' -f2) - - band=$(get_band_from_interface "${base_iface}") - - local wl_unit="" - - echo "${base_iface}" | grep '^wl[0-9]$' >/dev/null 2>&1 - if [ $? -eq 0 ]; then - wl_unit=$(echo "${base_iface}" | grep -o '[0-9]') - else - local unit - for unit in 0 1 2 3; do - local unit_iface=$(${NVRAM} get wl${unit}_ifname 2>/dev/null) - if [ "${unit_iface}" = "${base_iface}" ]; then - wl_unit="${unit}" - break + # Determine if it's a VIF (virtual interface) by checking nvram wlX_vifs + local is_vif=0 + for wl_unit in 0 1 2 3; do + local vifs=$(${NVRAM} get wl${wl_unit}_vifs 2>/dev/null) + if [ -n "${vifs}" ]; then + for vif in ${vifs}; do + if [ "${vif}" = "${iface}" ]; then + is_vif=1 + # Get the base interface to determine band + local base_iface=$(${NVRAM} get wl${wl_unit}_ifname 2>/dev/null) + band=$(get_band_from_interface "${base_iface}") + + # Get SSID for this VIF + guest_ssid=$(${NVRAM} get ${iface}_ssid 2>/dev/null) + if [ -z "${guest_ssid}" ] || [ "${guest_ssid}" = " " ]; then + guest_ssid="Guest Network" + fi + break 2 fi done fi + done - if [ -n "${wl_unit}" ]; then - guest_ssid=$(${NVRAM} get wl${wl_unit}.${guest_num}_ssid 2>/dev/null) - if [ -z "${guest_ssid}" ] || [ "${guest_ssid}" = " " ]; then - guest_ssid="Guest Network" - fi + # Determine type based on bridge membership and VIF status + if [ ${is_vif} -eq 1 ]; then + # It's a VIF - check which bridge it's on + if [ -n "${bridge_name}" ] && [ "${bridge_name}" != "br0" ]; then + type="guest" else - guest_ssid="Guest Network" + # VIF on br0 is treated as local Wi-Fi + type="main" fi - - type="guest" echo "${type}|${band}|${guest_ssid}" return fi + # Not a VIF - determine band for main interfaces band=$(get_band_from_interface "${iface}") if [ -n "${band}" ]; then @@ -207,23 +310,45 @@ bytes_to_gb() { fi } -# Get IP address for a MAC from ARP table +# Get IP address for a MAC from ARP table with MLO/MLD awareness +# Prefers IPs with REACHABLE or DELAY neighbor state for more reliable mapping get_ip_from_mac() { local mac="$1" + local dhcp_leases="$2" local ip="" local mac_normalized="" mac_normalized=$(echo "${mac}" | tr 'A-F' 'a-f') + # Get the lookup MAC (may be MLD MAC for WiFi 7 clients) + local lookup_mac=$(get_lookup_mac "${mac_normalized}" "${dhcp_leases}") + + # Try to find all IPs for this MAC in ARP table + local ips="" if [ -f /proc/net/arp ]; then - ip=$(grep -i "${mac}" /proc/net/arp 2>/dev/null | awk '{print $1}' | head -n1) + ips=$(awk -v mac="${mac_normalized}" 'BEGIN{IGNORECASE=1} tolower($4)==mac {print $1}' /proc/net/arp 2>/dev/null) + fi + + # If we have multiple IPs, prefer one that is REACHABLE or DELAY + if [ -n "${ips}" ]; then + for candidate_ip in ${ips}; do + local arp_status=$(ip neigh show | grep -w "${candidate_ip}" | awk '{print $NF}' 2>/dev/null) + if [ -n "${arp_status}" ] && { [ "${arp_status}" = "REACHABLE" ] || [ "${arp_status}" = "DELAY" ]; }; then + ip="${candidate_ip}" + break + fi + done + # If no REACHABLE/DELAY found, use the last IP as fallback + [ -z "${ip}" ] && ip=$(echo "${ips}" | tail -n 1) fi + # Try DHCP leases using lookup_mac if no IP found if [ -z "${ip}" ]; then - if [ -f /var/lib/misc/dnsmasq.leases ]; then - ip=$(awk -v mac="${mac_normalized}" '{if (tolower($2) == mac) {print $3; exit}}' /var/lib/misc/dnsmasq.leases 2>/dev/null) + if [ -f /var/lib/misc/dnsmasq.leases ]; then + ip=$(awk -v mac="${lookup_mac}" '{if (tolower($2) == mac) {print $3; exit}}' /var/lib/misc/dnsmasq.leases 2>/dev/null) fi fi + # Fallback to arp command if [ -z "${ip}" ]; then ip=$(${ARP} -n 2>/dev/null | grep -i "${mac}" | awk '{print $1}' | head -n1) fi @@ -235,182 +360,284 @@ get_ip_from_mac() { fi } -# Get hostname from dnsmasq leases and nvram - MAC-specific +# Get hostname from dnsmasq leases and nvram - MAC-specific with MLO/MLD support get_hostname() { local mac="$1" local ip="$2" + local dhcp_leases="$3" local hostname="" local mac_normalized="" mac_normalized=$(echo "${mac}" | tr 'A-F' 'a-f') - if [ -z "${hostname}" ] || [ "${hostname}" = "*" ]; then - local clientlist=$(${NVRAM} get custom_clientlist 2>/dev/null) - if [ -n "${clientlist}" ]; then - hostname=$(echo "${clientlist}" | tr '<' '\n' | grep -i "${mac}" | cut -d'>' -f1 | head -n1) - fi + # Get the lookup MAC (may be MLD MAC for WiFi 7 clients) + local lookup_mac=$(get_lookup_mac "${mac_normalized}" "${dhcp_leases}") + + # Try custom_clientlist first + local custom_clients=$(${NVRAM} get custom_clientlist 2>/dev/null) + if [ -n "${custom_clients}" ]; then + local mac_upper=$(echo "${mac}" | tr 'a-f' 'A-F') + hostname=$(echo "${custom_clients}" | grep -o "<[^>]*>${mac_upper}" | sed 's/^<\([^>]*\)>.*/\1/' | head -n1) fi - if [ -z "${hostname}" ] || [ "${hostname}" = "*" ]; then - if [ -f /var/lib/misc/dnsmasq.leases ]; then - hostname=$(awk -v mac="${mac_normalized}" '{if (tolower($2) == mac) {print $4; exit}}' /var/lib/misc/dnsmasq.leases 2>/dev/null) + # Try dnsmasq leases using lookup_mac + if [ -z "${hostname}" ] || [ "${hostname}" = " " ]; then + hostname=$(echo "${dhcp_leases}" | grep -i "${lookup_mac}" | awk '{print $4}' | head -n1) + fi + + # Try static DHCP reservations + if [ -z "${hostname}" ] || [ "${hostname}" = " " ] || [ "${hostname}" = "*" ]; then + local dhcp_staticlist=$(${NVRAM} get dhcp_staticlist 2>/dev/null) + if [ -n "${dhcp_staticlist}" ]; then + hostname=$(echo "${dhcp_staticlist}" | grep -i "${lookup_mac}" | cut -d'>' -f1 | sed 's/.*/dev/null) + # Fallback to reverse DNS lookup + if [ -z "${hostname}" ] || [ "${hostname}" = " " ] || [ "${hostname}" = "*" ]; then + if [ -n "${ip}" ] && [ "${ip}" != "Unknown" ]; then + hostname=$(nslookup "${ip}" 2>/dev/null | grep 'name =' | awk '{print $4}' | sed 's/\.$//') fi fi - if [ -z "${hostname}" ] || [ "${hostname}" = "*" ]; then - hostname="${mac}" + # Final fallback + if [ -z "${hostname}" ] || [ "${hostname}" = " " ] || [ "${hostname}" = "*" ]; then + hostname="Unknown" fi echo "${hostname}" } -################################################################################ -# WIRELESS CLIENT ENUMERATION -################################################################################ - -# Get wireless clients for a specific interface get_wireless_clients() { local iface="$1" - ${WL} -i "${iface}" assoclist 2>/dev/null | awk '/assoclist/ {print $2}' + ${WL} -i "${iface}" assoclist 2>/dev/null | awk '{print $2}' | tr 'A-F' 'a-f' } -# Get detailed wireless client information get_wireless_client_details() { local iface="$1" local mac="$2" - local ip="" + local dhcp_leases="$3" + local mac_normalized="" + local mac_upper="" + local clientip="" local hostname="" - local uptime="0" - local tx_bytes="0" - local rx_bytes="0" - local tx_rate="0" - local rx_rate="0" - local signal="0" - local bandwidth="" + local uptime="" + local tx_bytes="" + local rx_bytes="" + local tx_rate="" + local rx_rate="" + local rssi="" + local chanspec="" - ip=$(get_ip_from_mac "${mac}") - hostname=$(get_hostname "${mac}" "${ip}") - - sta_info=$(${WL} -i "${iface}" sta_info "${mac}" 2>/dev/null) - if [ -n "${sta_info}" ]; then - uptime=$(echo "${sta_info}" | grep 'in network' | awk '{for(i=1;i<=NF;i++){if($i=="network"){print $(i+1); exit}}}') - [ -z "${uptime}" ] && uptime="0" + mac_normalized=$(echo "${mac}" | tr 'A-F' 'a-f') + mac_upper=$(echo "${mac}" | tr 'a-f' 'A-F') - signal=$(echo "${sta_info}" | grep 'smoothed rssi:' | head -n1 | awk '{print $3}') - [ -z "${signal}" ] && signal="0" + # Get the lookup MAC for WiFi 7 / MLO clients + local lookup_mac=$(get_lookup_mac "${mac_normalized}" "${dhcp_leases}") - tx_rate=$(echo "${sta_info}" | grep 'rate of last tx pkt:' | awk '{print $6}') - rx_rate=$(echo "${sta_info}" | grep 'rate of last rx pkt:' | awk '{print $6}') - [ -z "${tx_rate}" ] && tx_rate="0" - [ -z "${rx_rate}" ] && rx_rate="0" + # For WiFi 7 / MLO clients the MAC used by wl (assoclist) may NOT be + # the same MAC that appears in ARP/DHCP. Start with the assoc MAC + # as canonical, then override if we find a better ARP match. + local canonical_mac="${mac}" + local canonlower="${mac_normalized}" + local canonupper="${mac_upper}" - # Get TX/RX bytes from wl sta_info + # Get client statistics from wl + local sta_info=$(${WL} -i "${iface}" sta_info "${mac}" 2>/dev/null) + + if [ -n "${sta_info}" ]; then + local network_time=$(echo "${sta_info}" | awk '/in network/ {print $3}') + if [ -n "${network_time}" ]; then + uptime=$(format_uptime "${network_time}") + else + uptime="Unknown" + fi + tx_bytes=$(echo "${sta_info}" | awk '/tx total bytes:/ {print $4}') rx_bytes=$(echo "${sta_info}" | awk '/rx data bytes:/ {print $4}') - [ -z "${tx_bytes}" ] && tx_bytes="0" - [ -z "${rx_bytes}" ] && rx_bytes="0" - - local bw_mhz="" - local nss="" + tx_rate=$(echo "${sta_info}" | awk '/rate of last tx pkt:/ {print $6}') + rx_rate=$(echo "${sta_info}" | awk '/rate of last rx pkt:/ {print $6}') + rssi=$(echo "${sta_info}" | awk '/smoothed rssi:/ {print $3}') + chanspec=$(echo "${sta_info}" | awk '/chanspec/ {print $2}') + fi - local link_bw_line=$(echo "${sta_info}" | grep -i 'link bandwidth') - if [ -n "${link_bw_line}" ]; then - bw_mhz=$(echo "${link_bw_line}" | grep -o '[0-9]\{2,3\}' | head -n1) + # Try to find IP for this MAC using MLO/MLD aware lookup + # 1) Try direct match in ARP table - collect all IPs + local ips="" + if [ -f /proc/net/arp ]; then + ips=$(awk -v mac="${mac_normalized}" 'BEGIN{IGNORECASE=1} tolower($4)==mac {print $1}' /proc/net/arp 2>/dev/null) + + # 2) If that fails, try a fuzzy match using the middle 4 bytes of the MAC + if [ -z "${ips}" ]; then + local mac_mid4=$(echo "${mac_normalized}" | awk -F: '{print $2":"$3":"$4":"$5}') + if [ -n "${mac_mid4}" ]; then + local arp_line=$(awk -v mid="${mac_mid4}" 'BEGIN{IGNORECASE=1} index(tolower($4), mid) > 0 {print; exit}' /proc/net/arp 2>/dev/null) + if [ -n "${arp_line}" ]; then + clientip=$(echo "${arp_line}" | awk '{print $1}') + canonical_mac=$(echo "${arp_line}" | awk '{print $4}') + canonlower=$(echo "${canonical_mac}" | tr 'A-F' 'a-f') + canonupper=$(echo "${canonical_mac}" | tr 'a-f' 'A-F') + fi + fi fi - if [ -z "${bw_mhz}" ]; then - local chanspec_line=$(echo "${sta_info}" | grep 'chanspec') - if [ -n "${chanspec_line}" ]; then - # Extract bandwidth from chanspec (format: "100/160" where 160 is the bandwidth) - # Check if there's a / in the chanspec line - if echo "${chanspec_line}" | grep '/' >/dev/null 2>&1; then - bw_mhz=$(echo "${chanspec_line}" | sed 's/.*\/\([0-9]\{2,3\}\).*/\1/') + # 3) If we had multiple IPs from direct match, prefer one that is REACHABLE/DELAY + if [ -z "${clientip}" ] && [ -n "${ips}" ]; then + for ip in ${ips}; do + local arp_status=$(ip neigh show | grep -w "${ip}" | awk '{print $NF}' 2>/dev/null) + if [ -z "${arp_status}" ] || { [ "${arp_status}" != "REACHABLE" ] && [ "${arp_status}" != "DELAY" ]; }; then + # Mark as stale if we have no signal strength + [ -z "${rssi}" ] && uptime="STALE" + continue else - bw_mhz=$(echo "${chanspec_line}" | grep -o '[0-9]\{2,3\}' | tail -n1) + clientip="${ip}" + break fi - fi + done + # If no REACHABLE/DELAY found, use the last IP as fallback + [ -z "${clientip}" ] && clientip=$(echo "${ips}" | tail -n 1) fi + fi - if [ -z "${bw_mhz}" ]; then - local omi_line=$(echo "${sta_info}" | grep 'OMI') - if [ -n "${omi_line}" ]; then - bw_mhz=$(echo "${omi_line}" | grep -o '[0-9]\{2,3\}[Mm][Hh][Zz]' | grep -o '[0-9]\{2,3\}') - fi - fi + # 4) Final fallback using canonical MAC + if [ -z "${clientip}" ]; then + clientip=$(awk -v mac="${canonlower}" 'BEGIN{IGNORECASE=1} tolower($4)==mac {print $1}' /proc/net/arp 2>/dev/null | sort | uniq | tail -n 1) + fi - local omi_line=$(echo "${sta_info}" | grep 'OMI') - if [ -n "${omi_line}" ]; then - nss=$(echo "${omi_line}" | grep -o 'tx=[0-9]ss' | grep -o '[0-9]' | head -n1) - fi + # If still no IP, try DHCP leases with lookup_mac + if [ -z "${clientip}" ]; then + clientip=$(echo "${dhcp_leases}" | grep -i "${lookup_mac}" | awk '{print $3}' | head -n1) + fi - if [ -z "${nss}" ]; then - local nrate_line=$(echo "${sta_info}" | grep 'tx nrate\|rx nrate' | head -n1) - if [ -n "${nrate_line}" ]; then - nss=$(echo "${nrate_line}" | grep -o 'Nss [0-9]' | grep -o '[0-9]') - fi + # For isolated guest networks, client may not appear in main ARP table + # Still display the client with "Unknown" IP if we have wireless stats + if [ -z "${clientip}" ]; then + if [ -n "${rssi}" ]; then + # Client is actively connected via wireless, just no IP visible + clientip="Unknown" + else + # No IP and no wireless stats - skip this client + return fi + fi - if [ -z "${nss}" ]; then - local vht_line=$(echo "${sta_info}" | grep 'VHT SET' -A 1 | tail -n1) - if [ -n "${vht_line}" ]; then - nss=$(echo "${vht_line}" | grep -o '[0-9]x[0-9]' | head -n1 | cut -d'x' -f1) - fi + # Check if this canonical MAC has already been processed + # This prevents the same device from appearing in both Wi-Fi and LAN sections + if [ -f "${PROCESSED_CLIENTS}" ]; then + if grep -qi "^${canonupper}$" "${PROCESSED_CLIENTS}" 2>/dev/null; then + return fi + fi + + # Track this canonical MAC as processed + echo "${canonupper}" >> "${PROCESSED_CLIENTS}" + + # Get hostname using MLO/MLD aware lookup + hostname=$(get_hostname "${canonical_mac}" "${clientip}" "${dhcp_leases}") + + # Convert traffic values + local tx_gb=$(bytes_to_gb "${tx_bytes:-0}") + local rx_gb=$(bytes_to_gb "${rx_bytes:-0}") + local tx_mbps=$(echo "${tx_rate:-0}" | awk '{printf "%.1f", $1/1000}') + local rx_mbps=$(echo "${rx_rate:-0}" | awk '{printf "%.1f", $1/1000}') - if [ -n "${bw_mhz}" ]; then - if [ -n "${nss}" ]; then - bandwidth="${nss}x${nss}:${bw_mhz}" + # Determine detailed band information (NSS and bandwidth) + local bandwidth="" + local bw_mhz="" + local nss="" + + # Try to extract bandwidth from various fields in sta_info + # Method 1: Check for "link bandwidth" line + local link_bw_line=$(echo "${sta_info}" | grep -i 'link bandwidth') + if [ -n "${link_bw_line}" ]; then + bw_mhz=$(echo "${link_bw_line}" | grep -o '[0-9]\{2,3\}' | head -n1) + fi + + # Method 2: Extract from chanspec if bandwidth not found + if [ -z "${bw_mhz}" ] && [ -n "${chanspec}" ]; then + local chanspec_line=$(echo "${sta_info}" | grep 'chanspec') + if [ -n "${chanspec_line}" ]; then + # Extract bandwidth from chanspec (format: "100/160" where 160 is the bandwidth) + if echo "${chanspec_line}" | grep '/' >/dev/null 2>&1; then + bw_mhz=$(echo "${chanspec_line}" | sed 's/.*\/\([0-9]\{2,3\}\).*/\1/') else - bandwidth="${bw_mhz}" + bw_mhz=$(echo "${chanspec_line}" | grep -o '[0-9]\{2,3\}' | tail -n1) fi + fi + fi + + # Method 3: Try OMI line for bandwidth + if [ -z "${bw_mhz}" ]; then + local omi_line=$(echo "${sta_info}" | grep 'OMI') + if [ -n "${omi_line}" ]; then + bw_mhz=$(echo "${omi_line}" | grep -o '[0-9]\{2,3\}[Mm][Hh][Zz]' | grep -o '[0-9]\{2,3\}') + fi + fi + + # Extract NSS (Number of Spatial Streams) + # Method 1: Check OMI line + local omi_line=$(echo "${sta_info}" | grep 'OMI') + if [ -n "${omi_line}" ]; then + nss=$(echo "${omi_line}" | grep -o 'tx=[0-9]ss' | grep -o '[0-9]' | head -n1) + fi + + # Method 2: Check nrate line if NSS not found + if [ -z "${nss}" ]; then + local nrate_line=$(echo "${sta_info}" | grep 'tx nrate\|rx nrate' | head -n1) + if [ -n "${nrate_line}" ]; then + nss=$(echo "${nrate_line}" | grep -o 'Nss [0-9]' | grep -o '[0-9]') + fi + fi + + # Method 3: Check VHT SET if NSS still not found + if [ -z "${nss}" ]; then + local vht_line=$(echo "${sta_info}" | grep 'VHT SET' -A 1 | tail -n1) + if [ -n "${vht_line}" ]; then + nss=$(echo "${vht_line}" | grep -o '[0-9]x[0-9]' | head -n1 | cut -d'x' -f1) + fi + fi + + # Format bandwidth display + if [ -n "${bw_mhz}" ]; then + if [ -n "${nss}" ]; then + bandwidth="${nss}x${nss}:${bw_mhz}" else - bandwidth="Unknown" - fi - fi - - # Format output - printf " %-14s | %-15s | %-17s | %7s | %5s | %5s | %7.1f | %7.1f | %3s | %s\n" \ - "${hostname}" \ - "${ip}" \ - "${mac}" \ - "$(format_uptime ${uptime})" \ - "$(bytes_to_gb ${tx_bytes})" \ - "$(bytes_to_gb ${rx_bytes})" \ - "$(echo ${tx_rate} | awk '{printf "%.1f", $1/1000}')" \ - "$(echo ${rx_rate} | awk '{printf "%.1f", $1/1000}')" \ - "${signal}" \ - "${bandwidth}" -} + bandwidth="0x0:${bw_mhz}" + fi + else + # Fallback to basic band from interface or chanspec + if [ -n "${chanspec}" ]; then + case "${chanspec}" in + *6g*) bandwidth="6G" ;; + *5g*) bandwidth="5G" ;; + *2g*) bandwidth="2.4G" ;; + *) bandwidth=$(get_band_from_interface "${iface}" | sed 's/GHz//; s/\.0//; s/-2$/2/') ;; + esac + else + bandwidth=$(get_band_from_interface "${iface}" | sed 's/GHz//; s/\.0//; s/-2$/2/') + fi + + # If still no bandwidth info, mark as unknown + [ -z "${bandwidth}" ] && bandwidth="?" + fi -################################################################################ -# LAN CLIENT ENUMERATION -################################################################################ + printf " %-14s | %-15s | %-17s | %7s | %5s | %5s | %7s | %7s | %3s | %s\n" \ + "${hostname}" "${clientip}" "${canonupper}" "${uptime}" \ + "${tx_gb}" "${rx_gb}" "${tx_mbps}" "${rx_mbps}" "${rssi:--}" "${bandwidth}" +} get_lan_clients() { - local wireless_macs="" - local iface + local dhcp_leases="$1" local temp_file="/tmp/lan_clients_$$.tmp" - for iface in $(get_wireless_interfaces); do - local clients=$(get_wireless_clients "${iface}") - if [ -n "${clients}" ]; then - wireless_macs="${wireless_macs} ${clients}" - fi - done - - wireless_macs=$(echo "${wireless_macs}" | tr 'A-F' 'a-f') - if [ -f /proc/net/arp ]; then ${CAT} /proc/net/arp | awk 'NR>1 && $3!="0x0" && $4!="00:00:00:00:00:00" {print $1, $4}' > "${temp_file}" else ${ARP} -n 2>/dev/null | awk 'NR>1 && $1!="?" {print $1, $3}' > "${temp_file}" fi + # Group IPs by MAC to handle multiple IPs per MAC + local processed_macs_local="" + while read ip mac; do [ -z "${mac}" ] || [ -z "${ip}" ] && continue [ "${ip}" = "IP" ] && continue @@ -420,19 +647,42 @@ get_lan_clients() { fi local mac_normalized=$(echo "${mac}" | tr 'A-F' 'a-f') - - local is_wireless=0 - for wmac in ${wireless_macs}; do - if [ "${mac_normalized}" = "${wmac}" ]; then - is_wireless=1 - break + local mac_upper=$(echo "${mac}" | tr 'a-f' 'A-F') + + # Skip if already processed this MAC in this function + echo "${processed_macs_local}" | grep -q "${mac_normalized}" && continue + + # Skip if this MAC was already shown in wireless section + if [ -f "${PROCESSED_CLIENTS}" ]; then + if grep -qi "^${mac_upper}$" "${PROCESSED_CLIENTS}" 2>/dev/null; then + continue fi - done + fi - if [ ${is_wireless} -eq 0 ]; then - local hostname=$(get_hostname "${mac}" "${ip}") - printf " %-14s | %-15s | %s\n" "${hostname}" "${ip}" "${mac}" + # Track this MAC as processed + echo "${mac_upper}" >> "${PROCESSED_CLIENTS}" + + # Find all IPs for this MAC and prefer REACHABLE/DELAY + local all_ips=$(grep -i "${mac}" "${temp_file}" | awk '{print $1}') + local best_ip="" + + if [ -n "${all_ips}" ]; then + for candidate_ip in ${all_ips}; do + local arp_status=$(ip neigh show | grep -w "${candidate_ip}" | awk '{print $NF}' 2>/dev/null) + if [ -n "${arp_status}" ] && { [ "${arp_status}" = "REACHABLE" ] || [ "${arp_status}" = "DELAY" ]; }; then + best_ip="${candidate_ip}" + break + fi + done + # Fallback to first IP if no REACHABLE/DELAY found + [ -z "${best_ip}" ] && best_ip=$(echo "${all_ips}" | head -n1) + else + best_ip="${ip}" fi + + local hostname=$(get_hostname "${mac}" "${best_ip}" "${dhcp_leases}") + printf " %-14s | %-15s | %s\n" "${hostname}" "${best_ip}" "${mac}" + processed_macs_local="${processed_macs_local} ${mac_normalized}" done < "${temp_file}" | sort -u rm -f "${temp_file}" @@ -449,6 +699,19 @@ get_primary_subnet() { fi } +# Get subnet for a specific bridge interface +get_bridge_subnet() { + local bridge="$1" + local bridge_ip=$(${IFCONFIG} "${bridge}" 2>/dev/null | grep 'inet addr:' | awk '{print $2}' | cut -d':' -f2) + if [ -z "${bridge_ip}" ]; then + bridge_ip=$(${IFCONFIG} "${bridge}" 2>/dev/null | awk '/inet / {print $2}') + fi + + if [ -n "${bridge_ip}" ]; then + echo "${bridge_ip}" | awk -F'.' '{print $1"."$2"."$3".0/24"}' + fi +} + get_unique_subnets() { local temp_file="/tmp/subnets_$$.tmp" local primary_subnet=$(get_primary_subnet) @@ -491,35 +754,63 @@ get_vlan_interface() { done } -get_vlan_clients() { - local subnet="$1" - local wireless_macs="$2" - local subnet_prefix=$(echo "${subnet}" | cut -d'/' -f1 | sed 's/\.0$//') - local temp_file="/tmp/vlan_clients_$$.tmp" +get_bridge_clients() { + local bridge="$1" + local dhcp_leases="$2" + local temp_file="/tmp/bridge_clients_$$.tmp" + # Get clients from ARP table that are on this specific bridge (Device column) if [ -f /proc/net/arp ]; then - ${CAT} /proc/net/arp | awk -v prefix="${subnet_prefix}" 'NR>1 && $3!="0x0" && $4!="00:00:00:00:00:00" && $1 ~ "^"prefix {print $1, $4}' > "${temp_file}" + ${CAT} /proc/net/arp | awk -v bridge="${bridge}" 'NR>1 && $3!="0x0" && $4!="00:00:00:00:00:00" && $6==bridge {print $1, $4, $6}' > "${temp_file}" else - ${ARP} -n 2>/dev/null | awk -v prefix="${subnet_prefix}" 'NR>1 && $1!="?" && $1 ~ "^"prefix {print $1, $3}' > "${temp_file}" + # Fallback: if arp command is used, we won't have bridge info + rm -f "${temp_file}" + return fi - while read ip mac; do + # Group IPs by MAC to handle multiple IPs per MAC + local processed_macs_local="" + + while read ip mac device; do [ -z "${mac}" ] || [ -z "${ip}" ] && continue local mac_normalized=$(echo "${mac}" | tr 'A-F' 'a-f') + local mac_upper=$(echo "${mac}" | tr 'a-f' 'A-F') - local is_wireless=0 - for wmac in ${wireless_macs}; do - if [ "${mac_normalized}" = "${wmac}" ]; then - is_wireless=1 - break - fi - done + # Skip if already processed this MAC in this function + echo "${processed_macs_local}" | grep -q "${mac_normalized}" && continue - if [ ${is_wireless} -eq 0 ]; then - local hostname=$(get_hostname "${mac}" "${ip}") - printf " %-14s | %-15s | %s\n" "${hostname}" "${ip}" "${mac}" + # Skip if this MAC was already shown in wireless section + if [ -f "${PROCESSED_CLIENTS}" ]; then + if grep -qi "^${mac_upper}$" "${PROCESSED_CLIENTS}" 2>/dev/null; then + continue + fi + fi + + # Track this MAC as processed + echo "${mac_upper}" >> "${PROCESSED_CLIENTS}" + + # Find all IPs for this MAC on this bridge and prefer REACHABLE/DELAY + local all_ips=$(grep -i "${mac}" "${temp_file}" | awk '{print $1}') + local best_ip="" + + if [ -n "${all_ips}" ]; then + for candidate_ip in ${all_ips}; do + local arp_status=$(ip neigh show | grep -w "${candidate_ip}" | awk '{print $NF}' 2>/dev/null) + if [ -n "${arp_status}" ] && { [ "${arp_status}" = "REACHABLE" ] || [ "${arp_status}" = "DELAY" ]; }; then + best_ip="${candidate_ip}" + break + fi + done + # Fallback to first IP if no REACHABLE/DELAY found + [ -z "${best_ip}" ] && best_ip=$(echo "${all_ips}" | head -n1) + else + best_ip="${ip}" fi + + local hostname=$(get_hostname "${mac}" "${best_ip}" "${dhcp_leases}") + printf " %-14s | %-15s | %s\n" "${hostname}" "${best_ip}" "${mac}" + processed_macs_local="${processed_macs_local} ${mac_normalized}" done < "${temp_file}" rm -f "${temp_file}" @@ -536,11 +827,17 @@ display_network_clients() { local band local guest_ssid local client_count - local wireless_macs="" + + # Initialize processed client tracking files + > "${PROCESSED_CLIENTS}" + > "${PROCESSED_VLAN_CLIENTS}" + + # Read DHCP leases once for MLO/MLD awareness + local dhcp_leases=$(read_all_dhcp_leases) echo "" echo "================================================================================" - echo " ASUS Network Client Monitor" + echo " ASUS Network Client Monitor PoC v10" echo " Asus-Merlin Firmware" echo " Generated: $(date '+%Y-%m-%d %H:%M:%S')" echo "================================================================================" @@ -561,10 +858,22 @@ display_network_clients() { client_count=$(echo "${client_list}" | wc -l) fi + # Get bridge information for display + local bridge_name=$(get_bridge_for_interface "${iface}") + local bridge_info="" + if [ -n "${bridge_name}" ]; then + bridge_info=" (Bridge: ${bridge_name})" + fi + if [ "${iface_type}" = "guest" ]; then - echo " Guest Wi-Fi: ${guest_ssid} - IFace: ${iface}" + echo " Guest Wi-Fi: ${guest_ssid}${bridge_info} - IFace: ${iface}" elif [ "${iface_type}" = "main" ]; then - echo " Local ${band} - IFace: ${iface}" + if [ -n "${guest_ssid}" ]; then + # This is a VIF on br0 (Local Wi-Fi on main bridge) + echo " Local Wi-Fi: ${guest_ssid}${bridge_info} - ${band} - IFace: ${iface}" + else + echo " Local ${band}${bridge_info} - IFace: ${iface}" + fi fi if [ "${iface_type}" = "main" ] || [ "${iface_type}" = "guest" ]; then @@ -572,52 +881,47 @@ display_network_clients() { "Name" "IP" "MAC" "Uptime" "TX GB" "RX GB" "TX Mbps" "RX Mbps" "Sig" "Band" if [ -n "${client_list}" ]; then + local temp_output="/tmp/netmon_client_output_$$.tmp" + > "${temp_output}" + for mac in ${client_list}; do - get_wireless_client_details "${iface}" "${mac}" + get_wireless_client_details "${iface}" "${mac}" "${dhcp_leases}" >> "${temp_output}" done + + if [ -s "${temp_output}" ]; then + ${CAT} "${temp_output}" + else + echo " No wireless clients connected" + fi + rm -f "${temp_output}" else - echo " No clients connected" + echo " No wireless clients connected" fi echo "" fi done - for iface in $(get_wireless_interfaces); do - local clients=$(get_wireless_clients "${iface}") - if [ -n "${clients}" ]; then - wireless_macs="${wireless_macs} ${clients}" - fi - done - wireless_macs=$(echo "${wireless_macs}" | tr 'A-F' 'a-f') - - local primary_subnet=$(get_primary_subnet) - local vlan_subnets=$(get_unique_subnets) - local has_vlans=0 - - if [ -n "${vlan_subnets}" ]; then - has_vlans=1 - fi - - if [ ${has_vlans} -eq 1 ]; then - echo " Local VLAN/AiMesh VLAN" - echo "" - - for subnet in ${vlan_subnets}; do - local subnet_prefix=$(echo "${subnet}" | cut -d'/' -f1 | sed 's/\.0$//') - local vlan_iface=$(get_vlan_interface "${subnet}") - - if [ -n "${vlan_iface}" ]; then - echo " VLAN ${subnet} - IFace: ${vlan_iface}" + # Get VLAN/AiMesh bridges from apg_ifnames (more accurate than subnet detection) + local vlan_bridges=$(get_vlan_bridges) + + if [ -n "${vlan_bridges}" ]; then + for bridge in ${vlan_bridges}; do + # Get subnet for this bridge if available + local bridge_subnet=$(get_bridge_subnet "${bridge}") + + if [ -n "${bridge_subnet}" ]; then + echo " Local VLAN/AiMesh VLAN ${bridge_subnet} - IFace: ${bridge}" else - echo " VLAN ${subnet}" + echo " Local VLAN/AiMesh VLAN - IFace: ${bridge}" fi printf " %-14s | %-15s | %s\n" "Name" "IP" "MAC" - local vlan_clients=$(get_vlan_clients "${subnet}" "${wireless_macs}") + # Use bridge-based client detection + local bridge_client_output=$(get_bridge_clients "${bridge}" "${dhcp_leases}") - if [ -n "${vlan_clients}" ]; then - echo "${vlan_clients}" + if [ -n "${bridge_client_output}" ]; then + echo "${bridge_client_output}" else echo " No wired clients found" fi @@ -625,22 +929,23 @@ display_network_clients() { done fi + local primary_subnet=$(get_primary_subnet) echo " Local LAN/Non-VLAN AiMesh - Subnet: ${primary_subnet} - IFace: br0" printf " %-14s | %-15s | %s\n" "Name" "IP" "MAC" - if [ -n "${primary_subnet}" ]; then - local primary_clients=$(get_vlan_clients "${primary_subnet}" "${wireless_macs}") - if [ -n "${primary_clients}" ]; then - echo "${primary_clients}" - else - echo " No wired clients found" - fi + # Use bridge-based detection for br0 clients + local br0_clients=$(get_bridge_clients "br0" "${dhcp_leases}") + if [ -n "${br0_clients}" ]; then + echo "${br0_clients}" else - get_lan_clients + echo " No wired clients found" fi echo "" echo "================================================================================" + + # Cleanup tracking files + rm -f "${PROCESSED_CLIENTS}" "${PROCESSED_VLAN_CLIENTS}" } ################################################################################ From e412d932741c0b71d84eead8cb8c0722c88bc3b5 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Sat, 13 Dec 2025 11:17:19 -0500 Subject: [PATCH 34/62] Remove unnecessary blank lines in netmon-poc.sh --- netmon-poc.sh | 68 +++++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/netmon-poc.sh b/netmon-poc.sh index aa17d84..09dcb98 100644 --- a/netmon-poc.sh +++ b/netmon-poc.sh @@ -105,7 +105,7 @@ read_all_dhcp_leases() { # Unified MLD MAC retrieval logic: given the current dhcpleases and association MAC (in lowercase), # determine the lookup MAC (which may be the MLD MAC if present). -# For WiFi 7 / MLO clients the MAC used by 'wl assoclist' may NOT be the same MAC +# For WiFi 7 / MLO clients the MAC used by 'wl assoclist' may NOT be the same MAC # that appears in ARP/DHCP. This function finds the correct MAC to use for lookups. get_lookup_mac() { local maclower="$1" @@ -114,7 +114,7 @@ get_lookup_mac() { local mld_line="" local field_count="" local mld_mac="" - + mld_line=$(echo "${leases}" | grep -i "${maclower}" | head -n1) if [ -n "${mld_line}" ]; then field_count=$(echo "${mld_line}" | awk '{print NF; exit}') @@ -136,14 +136,14 @@ get_lookup_mac() { get_bridge_for_interface() { local iface="$1" local bridge_name="" - + for br in $(ls /sys/class/net 2>/dev/null | grep '^br'); do if [ -d "/sys/class/net/${br}/brif/${iface}" ]; then bridge_name="${br}" break fi done - + echo "${bridge_name}" } @@ -175,14 +175,14 @@ is_local_ip() { # Get all active wireless interfaces including VIFs (guest networks) get_wireless_interfaces() { local temp_file="/tmp/wireless_ifaces_$$.tmp" - + # Get main wireless interfaces ${IFCONFIG} | grep '^eth[0-9]\|^wl[0-9]' | awk '{print $1}' | while read iface; do if ${WL} -i "${iface}" status >/dev/null 2>&1; then echo "${iface}" fi done > "${temp_file}" - + # Get VIFs (virtual interfaces for guest networks) from nvram for wl_unit in 0 1 2 3; do local vifs=$(${NVRAM} get wl${wl_unit}_vifs 2>/dev/null) @@ -199,7 +199,7 @@ get_wireless_interfaces() { done fi done >> "${temp_file}" - + # Sort and deduplicate sort -u "${temp_file}" rm -f "${temp_file}" @@ -253,7 +253,7 @@ get_interface_info() { # Get the base interface to determine band local base_iface=$(${NVRAM} get wl${wl_unit}_ifname 2>/dev/null) band=$(get_band_from_interface "${base_iface}") - + # Get SSID for this VIF guest_ssid=$(${NVRAM} get ${iface}_ssid 2>/dev/null) if [ -z "${guest_ssid}" ] || [ "${guest_ssid}" = " " ]; then @@ -443,7 +443,7 @@ get_wireless_client_details() { # Get client statistics from wl local sta_info=$(${WL} -i "${iface}" sta_info "${mac}" 2>/dev/null) - + if [ -n "${sta_info}" ]; then local network_time=$(echo "${sta_info}" | awk '/in network/ {print $3}') if [ -n "${network_time}" ]; then @@ -451,7 +451,7 @@ get_wireless_client_details() { else uptime="Unknown" fi - + tx_bytes=$(echo "${sta_info}" | awk '/tx total bytes:/ {print $4}') rx_bytes=$(echo "${sta_info}" | awk '/rx data bytes:/ {print $4}') tx_rate=$(echo "${sta_info}" | awk '/rate of last tx pkt:/ {print $6}') @@ -465,7 +465,7 @@ get_wireless_client_details() { local ips="" if [ -f /proc/net/arp ]; then ips=$(awk -v mac="${mac_normalized}" 'BEGIN{IGNORECASE=1} tolower($4)==mac {print $1}' /proc/net/arp 2>/dev/null) - + # 2) If that fails, try a fuzzy match using the middle 4 bytes of the MAC if [ -z "${ips}" ]; then local mac_mid4=$(echo "${mac_normalized}" | awk -F: '{print $2":"$3":"$4":"$5}') @@ -527,7 +527,7 @@ get_wireless_client_details() { return fi fi - + # Track this canonical MAC as processed echo "${canonupper}" >> "${PROCESSED_CLIENTS}" @@ -544,14 +544,14 @@ get_wireless_client_details() { local bandwidth="" local bw_mhz="" local nss="" - + # Try to extract bandwidth from various fields in sta_info # Method 1: Check for "link bandwidth" line local link_bw_line=$(echo "${sta_info}" | grep -i 'link bandwidth') if [ -n "${link_bw_line}" ]; then bw_mhz=$(echo "${link_bw_line}" | grep -o '[0-9]\{2,3\}' | head -n1) fi - + # Method 2: Extract from chanspec if bandwidth not found if [ -z "${bw_mhz}" ] && [ -n "${chanspec}" ]; then local chanspec_line=$(echo "${sta_info}" | grep 'chanspec') @@ -564,7 +564,7 @@ get_wireless_client_details() { fi fi fi - + # Method 3: Try OMI line for bandwidth if [ -z "${bw_mhz}" ]; then local omi_line=$(echo "${sta_info}" | grep 'OMI') @@ -572,14 +572,14 @@ get_wireless_client_details() { bw_mhz=$(echo "${omi_line}" | grep -o '[0-9]\{2,3\}[Mm][Hh][Zz]' | grep -o '[0-9]\{2,3\}') fi fi - + # Extract NSS (Number of Spatial Streams) # Method 1: Check OMI line local omi_line=$(echo "${sta_info}" | grep 'OMI') if [ -n "${omi_line}" ]; then nss=$(echo "${omi_line}" | grep -o 'tx=[0-9]ss' | grep -o '[0-9]' | head -n1) fi - + # Method 2: Check nrate line if NSS not found if [ -z "${nss}" ]; then local nrate_line=$(echo "${sta_info}" | grep 'tx nrate\|rx nrate' | head -n1) @@ -587,7 +587,7 @@ get_wireless_client_details() { nss=$(echo "${nrate_line}" | grep -o 'Nss [0-9]' | grep -o '[0-9]') fi fi - + # Method 3: Check VHT SET if NSS still not found if [ -z "${nss}" ]; then local vht_line=$(echo "${sta_info}" | grep 'VHT SET' -A 1 | tail -n1) @@ -595,7 +595,7 @@ get_wireless_client_details() { nss=$(echo "${vht_line}" | grep -o '[0-9]x[0-9]' | head -n1 | cut -d'x' -f1) fi fi - + # Format bandwidth display if [ -n "${bw_mhz}" ]; then if [ -n "${nss}" ]; then @@ -615,7 +615,7 @@ get_wireless_client_details() { else bandwidth=$(get_band_from_interface "${iface}" | sed 's/GHz//; s/\.0//; s/-2$/2/') fi - + # If still no bandwidth info, mark as unknown [ -z "${bandwidth}" ] && bandwidth="?" fi @@ -637,7 +637,7 @@ get_lan_clients() { # Group IPs by MAC to handle multiple IPs per MAC local processed_macs_local="" - + while read ip mac; do [ -z "${mac}" ] || [ -z "${ip}" ] && continue [ "${ip}" = "IP" ] && continue @@ -651,7 +651,7 @@ get_lan_clients() { # Skip if already processed this MAC in this function echo "${processed_macs_local}" | grep -q "${mac_normalized}" && continue - + # Skip if this MAC was already shown in wireless section if [ -f "${PROCESSED_CLIENTS}" ]; then if grep -qi "^${mac_upper}$" "${PROCESSED_CLIENTS}" 2>/dev/null; then @@ -665,7 +665,7 @@ get_lan_clients() { # Find all IPs for this MAC and prefer REACHABLE/DELAY local all_ips=$(grep -i "${mac}" "${temp_file}" | awk '{print $1}') local best_ip="" - + if [ -n "${all_ips}" ]; then for candidate_ip in ${all_ips}; do local arp_status=$(ip neigh show | grep -w "${candidate_ip}" | awk '{print $NF}' 2>/dev/null) @@ -679,7 +679,7 @@ get_lan_clients() { else best_ip="${ip}" fi - + local hostname=$(get_hostname "${mac}" "${best_ip}" "${dhcp_leases}") printf " %-14s | %-15s | %s\n" "${hostname}" "${best_ip}" "${mac}" processed_macs_local="${processed_macs_local} ${mac_normalized}" @@ -786,14 +786,14 @@ get_bridge_clients() { continue fi fi - + # Track this MAC as processed echo "${mac_upper}" >> "${PROCESSED_CLIENTS}" # Find all IPs for this MAC on this bridge and prefer REACHABLE/DELAY local all_ips=$(grep -i "${mac}" "${temp_file}" | awk '{print $1}') local best_ip="" - + if [ -n "${all_ips}" ]; then for candidate_ip in ${all_ips}; do local arp_status=$(ip neigh show | grep -w "${candidate_ip}" | awk '{print $NF}' 2>/dev/null) @@ -807,7 +807,7 @@ get_bridge_clients() { else best_ip="${ip}" fi - + local hostname=$(get_hostname "${mac}" "${best_ip}" "${dhcp_leases}") printf " %-14s | %-15s | %s\n" "${hostname}" "${best_ip}" "${mac}" processed_macs_local="${processed_macs_local} ${mac_normalized}" @@ -827,11 +827,11 @@ display_network_clients() { local band local guest_ssid local client_count - + # Initialize processed client tracking files > "${PROCESSED_CLIENTS}" > "${PROCESSED_VLAN_CLIENTS}" - + # Read DHCP leases once for MLO/MLD awareness local dhcp_leases=$(read_all_dhcp_leases) @@ -883,11 +883,11 @@ display_network_clients() { if [ -n "${client_list}" ]; then local temp_output="/tmp/netmon_client_output_$$.tmp" > "${temp_output}" - + for mac in ${client_list}; do get_wireless_client_details "${iface}" "${mac}" "${dhcp_leases}" >> "${temp_output}" done - + if [ -s "${temp_output}" ]; then ${CAT} "${temp_output}" else @@ -903,12 +903,12 @@ display_network_clients() { # Get VLAN/AiMesh bridges from apg_ifnames (more accurate than subnet detection) local vlan_bridges=$(get_vlan_bridges) - + if [ -n "${vlan_bridges}" ]; then for bridge in ${vlan_bridges}; do # Get subnet for this bridge if available local bridge_subnet=$(get_bridge_subnet "${bridge}") - + if [ -n "${bridge_subnet}" ]; then echo " Local VLAN/AiMesh VLAN ${bridge_subnet} - IFace: ${bridge}" else @@ -943,7 +943,7 @@ display_network_clients() { echo "" echo "================================================================================" - + # Cleanup tracking files rm -f "${PROCESSED_CLIENTS}" "${PROCESSED_VLAN_CLIENTS}" } From 1f086c95711163c36767b221349d1b884944176b Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Sat, 13 Dec 2025 13:29:32 -0500 Subject: [PATCH 35/62] Update netmon-poc.sh --- netmon-poc.sh | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/netmon-poc.sh b/netmon-poc.sh index 09dcb98..2ac0e65 100644 --- a/netmon-poc.sh +++ b/netmon-poc.sh @@ -224,6 +224,23 @@ get_band_from_interface() { fi } +# Get SSID for a main wireless interface +get_ssid_for_interface() { + local iface="$1" + local ssid="" + + # Find the wl unit number for this interface + for wl_unit in 0 1 2 3; do + local unit_iface=$(${NVRAM} get wl${wl_unit}_ifname 2>/dev/null) + if [ "${unit_iface}" = "${iface}" ]; then + ssid=$(${NVRAM} get wl${wl_unit}_ssid 2>/dev/null) + break + fi + done + + echo "${ssid}" +} + # Get interface type and band information # Uses bridge membership to accurately determine guest vs local Wi-Fi get_interface_info() { @@ -837,7 +854,7 @@ display_network_clients() { echo "" echo "================================================================================" - echo " ASUS Network Client Monitor PoC v10" + echo " ASUS Network Client Monitor PoC v12" echo " Asus-Merlin Firmware" echo " Generated: $(date '+%Y-%m-%d %H:%M:%S')" echo "================================================================================" @@ -866,11 +883,12 @@ display_network_clients() { fi if [ "${iface_type}" = "guest" ]; then - echo " Guest Wi-Fi: ${guest_ssid}${bridge_info} - IFace: ${iface}" + echo " Guest ${band} Wi-Fi: ${guest_ssid}${bridge_info} - IFace: ${iface}" elif [ "${iface_type}" = "main" ]; then - if [ -n "${guest_ssid}" ]; then - # This is a VIF on br0 (Local Wi-Fi on main bridge) - echo " Local Wi-Fi: ${guest_ssid}${bridge_info} - ${band} - IFace: ${iface}" + # Get SSID for main wireless interfaces + local main_ssid=$(get_ssid_for_interface "${iface}") + if [ -n "${main_ssid}" ]; then + echo " Local ${band} Wi-Fi: ${main_ssid}${bridge_info} - IFace: ${iface}" else echo " Local ${band}${bridge_info} - IFace: ${iface}" fi From 3c4f123ff41942d1f72568393cbe93640498251e Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Sun, 14 Dec 2025 09:47:10 -0500 Subject: [PATCH 36/62] Major revisions to Wired/Wireless Network Connections --- rtrmon.sh | 2172 ++++++++++++++++++++++++++++------------------------- 1 file changed, 1164 insertions(+), 1008 deletions(-) diff --git a/rtrmon.sh b/rtrmon.sh index 5f564e8..0f41382 100644 --- a/rtrmon.sh +++ b/rtrmon.sh @@ -15,7 +15,7 @@ # # Please use the 'sh rtrmon.sh -setup' command to configure the necessary parameters that match your environment the best! # -# Last Modified: 2025-Dec-7 +# Last Modified: 2025-Dec-14 ########################################################################################################################### #Preferred standard router binaries path @@ -24,7 +24,7 @@ export PATH="/sbin:/bin:/usr/sbin:/usr/bin:$PATH" # ------------------------------------------------------------------------------------------------------------------------- # System Variables (Do not change beyond this point or this may change the programs ability to function correctly) # ------------------------------------------------------------------------------------------------------------------------- -Version="2.2.4b3" +Version="2.3.0b4" Beta=1 ScreenshotMode=0 LOGFILE="/jffs/addons/rtrmon.d/rtrmon.log" # Logfile path/name that captures important date/time events - change @@ -135,6 +135,8 @@ w52updown="UP" w6updown="UP" w62updown="UP" SortbyOpt="Name" +PreventScrolling=1 # PreventScrolling: 0=Show all output, 1=Paginate output +MaxRows=24 # MaxRows: Maximum rows to display before pausing (only used if PreventScrolling=1) ##-------------------------------------## ## Added by Martinski W. [2024-Nov-04] ## @@ -208,7 +210,7 @@ showheader() #Display RTRMON client header echo -en "${InvGreen} ${InvDkGray}${CWhite} RTRMON - v" printf "%-8s" $Version - echo -e " ${CGreen}(S)${CWhite}how/${CGreen}(H)${CWhite}ide Operations Menu ${InvDkGray} $tzspaces$(date +"%a %b %d, %Y %H:%M:%S %Z %z") ${CClear}" + echo -e " ${CGreen}(S)${CWhite}how/${CGreen}(H)${CWhite}ide Operations Menu ${InvDkGray} $tzspaces$(date +"%a %b %d, %Y %H:%M:%S %Z %z") ${CClear}" } # ------------------------------------------------------------------------------------------------------------------------- @@ -221,23 +223,23 @@ displayopsmenu() { amtmdisp="${CDkGray}[n/a] " - echo -e "${InvGreen} ${InvDkGray}${CWhite} Operations Menu ${CClear}" + echo -e "${InvGreen} ${InvDkGray}${CWhite} Operations Menu ${CClear}" if [ "$vpn1on" == "True" ] || [ "$vpn2on" == "True" ] || [ "$vpn3on" == "True" ] || [ "$vpn4on" == "True" ] || [ "$vpn5on" == "True" ] then - echo -e "${InvGreen} ${CClear} Speedtest ${CGreen}(I)${CClear} WAN / VPN 1:${CGreen}(1)${CClear} 2:${CGreen}(2)${CClear} 3:${CGreen}(3)${CClear} 4:${CGreen}(4)${CClear} 5:${CGreen}(5)${CClear} ${InvGreen} ${CClear} ${CGreen}(M)${CClear}ain Setup Menu / Configuration Menu${CClear}" + echo -e "${InvGreen} ${CClear} Speedtest ${CGreen}(I)${CClear} WAN / VPN 1:${CGreen}(1)${CClear} 2:${CGreen}(2)${CClear} 3:${CGreen}(3)${CClear} 4:${CGreen}(4)${CClear} 5:${CGreen}(5)${CClear} ${InvGreen} ${CClear} ${CGreen}(M)${CClear}ain Setup Menu / Configuration Menu${CClear}" else - echo -e "${InvGreen} ${CClear} Speedtest ${CGreen}(I)${CClear} WAN ${CDkGray}/ VPN 1:(1) 2:(2) 3:(3) 4:(4) 5:(5)${CClear} ${InvGreen} ${CClear} ${CGreen}(M)${CClear}ain Setup Menu / Configuration Menu${CClear}" + echo -e "${InvGreen} ${CClear} Speedtest ${CGreen}(I)${CClear} WAN ${CDkGray}/ VPN 1:(1) 2:(2) 3:(3) 4:(4) 5:(5)${CClear} ${InvGreen} ${CClear} ${CGreen}(M)${CClear}ain Setup Menu / Configuration Menu${CClear}" fi if [ "$wg1on" == "True" ] || [ "$wg2on" == "True" ] || [ "$wg3on" == "True" ] || [ "$wg4on" == "True" ] || [ "$wg5on" == "True" ] then - echo -e "${InvGreen} ${CClear} Speedtest Wireguard 1:${CGreen}(6)${CClear} 2:${CGreen}(7)${CClear} 3:${CGreen}(8)${CClear} 4:${CGreen}(9)${CClear} 5:${CGreen}(0)${CClear} ${InvGreen} ${CClear} L${CGreen}(O)${CClear}g Viewer / Trim Log Size (rows): ${CGreen}$LOGSIZE${CClear}" + echo -e "${InvGreen} ${CClear} Speedtest Wireguard 1:${CGreen}(6)${CClear} 2:${CGreen}(7)${CClear} 3:${CGreen}(8)${CClear} 4:${CGreen}(9)${CClear} 5:${CGreen}(0)${CClear} ${InvGreen} ${CClear} L${CGreen}(O)${CClear}g Viewer / Trim Log Size (rows): ${CGreen}$LOGSIZE${CClear}" else - echo -e "${InvGreen} ${CClear} ${CDkGray}Speedtest Wireguard 1:(6) 2:(7) 3:(8) 4:(9) 5:(0)${CClear} ${InvGreen} ${CClear} L${CGreen}(O)${CClear}g Viewer / Trim Log Size (rows): ${CGreen}$LOGSIZE${CClear}" + echo -e "${InvGreen} ${CClear} ${CDkGray}Speedtest Wireguard 1:(6) 2:(7) 3:(8) 4:(9) 5:(0)${CClear} ${InvGreen} ${CClear} L${CGreen}(O)${CClear}g Viewer / Trim Log Size (rows): ${CGreen}$LOGSIZE${CClear}" fi - echo -e "${InvGreen} ${CClear} Run Router Network ${CGreen}(D)${CClear}iagnostics ${InvGreen} ${CClear} ${CGreen}(N)${CClear}ext Page / ${CGreen}(P)${CClear}revious Page: ${CGreen}($NextPage/7)${CClear}" - echo -e "${InvGreen} ${CClear} Refresh ${CGreen}(C)${CClear}urrent Network Statistics ${InvGreen} ${CClear} Auto ${CGreen}(R)${CClear}otate Pages Option: ${CGreen}$autorotateindicator${CClear}" - echo -e "${InvGreen} ${CClear} View ${CGreen}(W)${CClear}AN / ${CGreen}(L)${CClear}AN / ${CGreen}(V)${CClear}PN / W${CGreen}(G)${CClear} Stats ${InvGreen} ${CClear} Router Model/FW: ${CGreen}${RouterModel} | ${FWBUILD}${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo -e "${InvGreen} ${CClear} Run Router Network ${CGreen}(D)${CClear}iagnostics ${InvGreen} ${CClear} ${CGreen}(N)${CClear}ext Page / ${CGreen}(P)${CClear}revious Page: ${CGreen}($NextPage/7)${CClear}" + echo -e "${InvGreen} ${CClear} Refresh ${CGreen}(C)${CClear}urrent Network Statistics ${InvGreen} ${CClear} Auto ${CGreen}(R)${CClear}otate Pages Option: ${CGreen}$autorotateindicator${CClear}" + echo -e "${InvGreen} ${CClear} View ${CGreen}(W)${CClear}AN / ${CGreen}(L)${CClear}AN / ${CGreen}(V)${CClear}PN / W${CGreen}(G)${CClear} Stats ${InvGreen} ${CClear} Router Model/FW: ${CGreen}${RouterModel} | ${FWBUILD}${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}------------------------------------------------------------------------------------------------------------------------${CClear}" echo "" } @@ -540,6 +542,8 @@ progressbaroverride() if [ "$key_press" ] then case "$key_press" in + [Aa]) if [ "$PreventScrolling" = "1" ]; then PreventScrolling=0; elif [ "$PreventScrolling" = "0" ]; then PreventScrolling=1; fi; + timerReset=1;; [Cc]) QueueNetworkConn=1 echo -e "${CClear}[Queuing Network Connection Stats] "; sleep 1; NextPage=6; timerReset=1 @@ -2639,63 +2643,63 @@ DisplayPage1() fi showheader echo "" - echo -e "${InvDkGray}${CWhite} CPU ${CClear}" + echo -e "${InvDkGray}${CWhite} CPU ${CClear}" echo "" - echo -e "${InvGreen} ${CClear} ${CWhite}Uptime ${CDkGray}[ ${CWhite}$uptimeStr${CDkGray} ]${CClear}" - echo -e "${InvGreen} ${CClear} ${CWhite}CPU Load ${CDkGray}[ ${CGreen}1m: ${CWhite}$cpuload1m ${CGreen}5m: ${CWhite}$cpuload5m ${CGreen}15m: ${CWhite}$cpuload15m${CDkGray} ]${CClear}" - preparebar 79 "|" + echo -e "${InvGreen} ${CClear} ${CWhite}Uptime ${CDkGray}[ ${CWhite}$uptimeStr${CDkGray} ]${CClear}" + echo -e "${InvGreen} ${CClear} ${CWhite}CPU Load ${CDkGray}[ ${CGreen}1m: ${CWhite}$cpuload1m ${CGreen}5m: ${CWhite}$cpuload5m ${CGreen}15m: ${CWhite}$cpuload15m${CDkGray} ]${CClear}" + preparebar 89 "|" progressbar $oldcpuusr1 100 " CPU User " "%%" "Standard" $olddisplaycpuusr1 echo "" - preparebar 79 "|" + preparebar 89 "|" progressbar $oldcpusys1 100 " CPU System" "%%" "Standard" $olddisplaycpusys1 echo "" - preparebar 79 "|" + preparebar 89 "|" progressbar $oldcpunice1 100 " CPU Nice " "%%" "Standard" $olddisplaycpunice1 echo "" - preparebar 79 "|" + preparebar 89 "|" progressbar $oldcpuidle1 100 " CPU Idle " "%%" "Reverse" $olddisplaycpuidle1 echo "" - preparebar 79 "|" + preparebar 89 "|" progressbar $oldcpuirq1 100 " CPU IRQ " "%%" "Standard" $olddisplaycpuirq1 echo "" - preparebar 79 "|" + preparebar 89 "|" converttemps $oldF_cputemp progressbar $currenttemp $currentrange " CPU Temp " $TempUnits "CPU" $currenttemp $currentrange echo "" echo "" - echo -e "${InvDkGray}${CWhite} Memory ${CClear}" + echo -e "${InvDkGray}${CWhite} Memory ${CClear}" echo "" - echo -en "${InvGreen} ${CClear} ${CWhite}Mem Total ${CDkGray}[ ${CWhite}" + echo -en "${InvGreen} ${CClear} ${CWhite}Mem Total ${CDkGray}[ ${CWhite}" printf "%-7s" "$totalphysmem MB" - echo -e "${CDkGray} ]${CClear}" - preparebar 79 "|" + echo -e "${CDkGray} ]${CClear}" + preparebar 89 "|" progressbar $oldmemused2 $oldtotalmemory " Mem Used " "MB" "Standard" echo "" - preparebar 79 "|" + preparebar 89 "|" progressbar $oldmemfree2 $oldtotalmemory " Mem Free " "MB" "Reverse" echo "" - preparebar 79 "|" + preparebar 89 "|" progressbar $oldmemshrd2 $oldtotalmemory " Mem Shared" "MB" "Standard" echo "" - preparebar 79 "|" + preparebar 89 "|" progressbar $oldmembuff2 $oldtotalmemory " Mem Buffer" "MB" "Standard" echo "" - preparebar 79 "|" + preparebar 89 "|" progressbar $oldmemcach2 $oldtotalmemory " Mem Cache " "MB" "Standard" echo "" - preparebar 79 "|" + preparebar 89 "|" progressbar $oldnvramused $oldtotalnvram " NVRAM Used" "B" "Standard" echo "" echo "" - echo -e "${InvDkGray}${CWhite} Disk ${CClear}" + echo -e "${InvDkGray}${CWhite} Disk ${CClear}" echo "" - echo -en "${InvGreen} ${CClear} ${CWhite}Swap Size ${CDkGray}[ ${CWhite}" + echo -en "${InvGreen} ${CClear} ${CWhite}Swap Size ${CDkGray}[ ${CWhite}" printf "%-8s" "$swaptotal MB" - echo -e "${CDkGray} ]${CClear}" - preparebar 79 "|" + echo -e "${CDkGray} ]${CClear}" + preparebar 89 "|" progressbar $oldswapused $oldswaptotal " Swap Used " "MB" "Standard" echo "" - preparebar 79 "|" + preparebar 89 "|" progressbar $oldjffsused $oldjffstotal " JFFS Used " "MB" "Standard" #Disk - SD devices @@ -2726,7 +2730,7 @@ DisplayPage1() sdnameformat=$(printf "%-10s" $sdname) echo "" - preparebar 79 "|" + preparebar 89 "|" progressbar $sdused $sdtotal " $sdnameformat" "GB" "Standard" done } @@ -2743,7 +2747,7 @@ DisplayPage2() showheader if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then echo "" - echo -e "${InvDkGray}${CWhite} WAN ${CClear}" + echo -e "${InvDkGray}${CWhite} WAN ${CClear}" echo "" if [ "$ScreenshotMode" == "1" ]; then oldwan0ip="1.2.3.4" #demo @@ -2773,341 +2777,341 @@ DisplayPage2() printf '%03d.%03d.%03d.%03d' ${oldwan0ip//./ } echo -en " / " printf '%03d.%03d.%03d.%03d' ${oldwan1ip//./ } - echo -en "${CDkGray} ] ${CWhite} DNS ${CDkGray}[ ${CWhite}" - if [ $olddns1ip = "0.0.0.0" ]; then printf "000.000.000.000"; else printf '%03d.%03d.%03d.%03d' ${olddns1ip//./ }; fi + echo -en "${CDkGray} ] ${CWhite} DNS ${CDkGray}[ ${CWhite}" + if [ $olddns1ip = "0.0.0.0" ]; then printf "000.000.000.000"; else printf '%03d.%03d.%03d.%03d' ${olddns1ip//./ }; fi echo -en " / " - if [ $olddns2ip = "0.0.0.0" ]; then printf "000.000.000.000"; else printf '%03d.%03d.%03d.%03d' ${olddns2ip//./ }; fi - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}IFace: $WANIFNAME${CClear}" + if [ $olddns2ip = "0.0.0.0" ]; then printf "000.000.000.000"; else printf '%03d.%03d.%03d.%03d' ${olddns2ip//./ }; fi + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}IFace: $WANIFNAME${CClear}" if [ ! -z $oldwanip6 ]; then echo -e "${InvGreen} ${CClear} ${CWhite}WAN 0/1 I6 ${CDkGray}[ ${CWhite}$oldwanip6${CClear}"; fi - preparebar 79 "|" + preparebar 89 "|" progressbar $oldwanrxmbrate $MaxSpeedInet " Avg WAN RX" "Mbps" "Standard" $oldwanrxmbratedisplay $MaxSpeedInet echo "" - preparebar 79 "|" + preparebar 89 "|" progressbar $oldwantxmbrate $MaxSpeedInetUL " Avg WAN TX" "Mbps" "Standard" $oldwantxmbratedisplay $MaxSpeedInetUL echo "" fi echo "" - echo -e "${InvDkGray}${CWhite} LAN ${CClear}" + echo -e "${InvDkGray}${CWhite} LAN ${CClear}" echo "" echo -en "${InvGreen} ${CClear}${CWhite} BR0 LAN IP ${CDkGray}[ ${CWhite}" printf '%03d.%03d.%03d.%03d' ${oldlanip//./ } - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}IFace: br0${CClear}" + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}IFace: br0${CClear}" if [ ! -z $oldlanip6 ]; then echo -e "${InvGreen} ${CClear} ${CWhite}BR0 LAN I6 ${CDkGray}[ ${CWhite}$oldlanip6${CClear}"; fi - preparebar 79 "|" + preparebar 89 "|" progressbar $oldlanrxmbrate $MaxSpeedLAN " Avg LAN RX" "Mbps" "Standard" $oldlanrxmbratedisplay $MaxSpeedLAN echo "" - preparebar 79 "|" + preparebar 89 "|" if [ ${oldlantxmbrate%.*} -lt 0 ]; then oldlantxmbrate=0; oldlantxmbratedisplay=0; fi progressbar $oldlantxmbrate $MaxSpeedLAN " Avg LAN TX" "Mbps" "Standard" $oldlantxmbratedisplay $MaxSpeedLAN if [ "$vpn1on" == "True" ]; then echo "" echo "" - echo -e "${InvDkGray}${CWhite} OVPN$vpn1slot ${CClear}" + echo -e "${InvDkGray}${CWhite} OVPN$vpn1slot ${CClear}" echo "" if [ "$oldvpn1city" == "Private Network" ]; then echo -en "${InvGreen} ${CClear}${CWhite} PRV VPN IP ${CDkGray}[ ${CWhite}" printf '%03d.%03d.%03d.%03d' ${oldvpn1ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" printf "%-33s" "$oldvpn1city" - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn1slot${CClear}" + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn1slot${CClear}" else echo -en "${InvGreen} ${CClear}${CWhite} PUB VPN IP ${CDkGray}[ ${CWhite}" printf '%03d.%03d.%03d.%03d' ${oldvpn1ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" printf "%-33s" "$oldvpn1city" - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn1slot${CClear}" + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn1slot${CClear}" fi if [ ${oldvpntxmbrate%.*} -lt 0 ]; then oldvpntxmbrate=0; oldvpntxmbratedisplay=0; fi - preparebar 79 "|" + preparebar 89 "|" progressbar $oldvpntxmbrate $MaxSpeedInet " Avg VPN RX" "Mbps" "Standard" $oldvpntxmbratedisplay $MaxSpeedInet echo "" if [ ${oldvpnrxmbrate%.*} -lt 0 ]; then oldvpnrxmbrate=0; oldvpnrxmbratedisplay=0; fi - preparebar 79 "|" + preparebar 89 "|" progressbar $oldvpnrxmbrate $MaxSpeedInetUL " Avg VPN TX" "Mbps" "Standard" $oldvpnrxmbratedisplay $MaxSpeedInetUL fi if [ "$vpn2on" == "True" ]; then echo "" echo "" - echo -e "${InvDkGray}${CWhite} OVPN$vpn2slot ${CClear}" + echo -e "${InvDkGray}${CWhite} OVPN$vpn2slot ${CClear}" echo "" if [ "$oldvpn2city" == "Private Network" ]; then echo -en "${InvGreen} ${CClear}${CWhite} PRV VPN IP ${CDkGray}[ ${CWhite}" printf '%03d.%03d.%03d.%03d' ${oldvpn2ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" printf "%-33s" "$oldvpn2city" - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn2slot${CClear}" + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn2slot${CClear}" else echo -en "${InvGreen} ${CClear}${CWhite} PUB VPN IP ${CDkGray}[ ${CWhite}" printf '%03d.%03d.%03d.%03d' ${oldvpn2ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" printf "%-33s" "$oldvpn2city" - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn2slot${CClear}" + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn2slot${CClear}" fi if [ ${oldvpn2txmbrate%.*} -lt 0 ]; then oldvpn2txmbrate=0; oldvpn2txmbratedisplay=0; fi - preparebar 79 "|" + preparebar 89 "|" progressbar $oldvpn2txmbrate $MaxSpeedInet " Avg VPN RX" "Mbps" "Standard" $oldvpn2txmbratedisplay $MaxSpeedInet echo "" if [ ${oldvpn2rxmbrate%.*} -lt 0 ]; then oldvpn2rxmbrate=0; oldvpn2rxmbratedisplay=0; fi - preparebar 79 "|" + preparebar 89 "|" progressbar $oldvpn2rxmbrate $MaxSpeedInetUL " Avg VPN TX" "Mbps" "Standard" $oldvpn2rxmbratedisplay $MaxSpeedInetUL fi if [ "$vpn3on" == "True" ]; then echo "" echo "" - echo -e "${InvDkGray}${CWhite} OVPN$vpn3slot ${CClear}" + echo -e "${InvDkGray}${CWhite} OVPN$vpn3slot ${CClear}" echo "" if [ "$oldvpn3city" == "Private Network" ]; then echo -en "${InvGreen} ${CClear}${CWhite} PRV VPN IP ${CDkGray}[ ${CWhite}" printf '%03d.%03d.%03d.%03d' ${oldvpn3ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" printf "%-33s" "$oldvpn3city" - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn3slot${CClear}" + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn3slot${CClear}" else echo -en "${InvGreen} ${CClear}${CWhite} PUB VPN IP ${CDkGray}[ ${CWhite}" printf '%03d.%03d.%03d.%03d' ${oldvpn3ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" printf "%-33s" "$oldvpn3city" - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn3slot${CClear}" + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn3slot${CClear}" fi if [ ${oldvpn3txmbrate%.*} -lt 0 ]; then oldvpn3txmbrate=0; oldvpn3txmbratedisplay=0; fi - preparebar 79 "|" + preparebar 89 "|" progressbar $oldvpn3txmbrate $MaxSpeedInet " Avg VPN RX" "Mbps" "Standard" $oldvpn3txmbratedisplay $MaxSpeedInet echo "" if [ ${oldvpn3rxmbrate%.*} -lt 0 ]; then oldvpn3rxmbrate=0; oldvpn3rxmbratedisplay=0; fi - preparebar 79 "|" + preparebar 89 "|" progressbar $oldvpn3rxmbrate $MaxSpeedInetUL " Avg VPN TX" "Mbps" "Standard" $oldvpn3rxmbratedisplay $MaxSpeedInetUL fi if [ "$vpn4on" == "True" ]; then echo "" echo "" - echo -e "${InvDkGray}${CWhite} OVPN$vpn4slot ${CClear}" + echo -e "${InvDkGray}${CWhite} OVPN$vpn4slot ${CClear}" echo "" if [ "$oldvpn4city" == "Private Network" ]; then echo -en "${InvGreen} ${CClear}${CWhite} PRV VPN IP ${CDkGray}[ ${CWhite}" printf '%03d.%03d.%03d.%03d' ${oldvpn4ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" printf "%-33s" "$oldvpn4city" - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn4slot${CClear}" + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn4slot${CClear}" else echo -en "${InvGreen} ${CClear}${CWhite} PUB VPN IP ${CDkGray}[ ${CWhite}" printf '%03d.%03d.%03d.%03d' ${oldvpn4ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" printf "%-33s" "$oldvpn4city" - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn4slot${CClear}" + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn4slot${CClear}" fi if [ ${oldvpn4txmbrate%.*} -lt 0 ]; then oldvpn4txmbrate=0; oldvpn4txmbratedisplay=0; fi - preparebar 79 "|" + preparebar 89 "|" progressbar $oldvpn4txmbrate $MaxSpeedInet " Avg VPN RX" "Mbps" "Standard" $oldvpn4txmbratedisplay $MaxSpeedInet echo "" if [ ${oldvpn4rxmbrate%.*} -lt 0 ]; then oldvpn4rxmbrate=0; oldvpn4rxmbratedisplay=0; fi - preparebar 79 "|" + preparebar 89 "|" progressbar $oldvpn4rxmbrate $MaxSpeedInetUL " Avg VPN TX" "Mbps" "Standard" $oldvpn4rxmbratedisplay $MaxSpeedInetUL fi if [ "$vpn5on" == "True" ]; then echo "" echo "" - echo -e "${InvDkGray}${CWhite} OVPN$vpn5slot ${CClear}" + echo -e "${InvDkGray}${CWhite} OVPN$vpn5slot ${CClear}" echo "" if [ "$oldvpn5city" == "Private Network" ]; then echo -en "${InvGreen} ${CClear}${CWhite} PRV VPN IP ${CDkGray}[ ${CWhite}" printf '%03d.%03d.%03d.%03d' ${oldvpn5ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" printf "%-33s" "$oldvpn5city" - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn5slot${CClear}" + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn5slot${CClear}" else echo -en "${InvGreen} ${CClear}${CWhite} PUB VPN IP ${CDkGray}[ ${CWhite}" printf '%03d.%03d.%03d.%03d' ${oldvpn5ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" printf "%-33s" "$oldvpn5city" - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn5slot${CClear}" + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: tun1$vpn5slot${CClear}" fi if [ ${oldvpn5txmbrate%.*} -lt 0 ]; then oldvpn5txmbrate=0; oldvpn5txmbratedisplay=0; fi - preparebar 79 "|" + preparebar 89 "|" progressbar $oldvpn5txmbrate $MaxSpeedInet " Avg VPN RX" "Mbps" "Standard" $oldvpn5txmbratedisplay $MaxSpeedInet echo "" if [ ${oldvpn5rxmbrate%.*} -lt 0 ]; then oldvpn5rxmbrate=0; oldvpn5rxmbratedisplay=0; fi - preparebar 79 "|" + preparebar 89 "|" progressbar $oldvpn5rxmbrate $MaxSpeedInetUL " Avg VPN TX" "Mbps" "Standard" $oldvpn5rxmbratedisplay $MaxSpeedInetUL fi if [ "$wg1on" == "True" ]; then echo "" echo "" - echo -e "${InvDkGray}${CWhite} WG$wg1slot ${CClear}" + echo -e "${InvDkGray}${CWhite} WG$wg1slot ${CClear}" echo "" if [ "$oldwg1city" == "Private Network" ]; then echo -en "${InvGreen} ${CClear}${CWhite} PRV WG IP ${CDkGray}[ ${CWhite}" printf '%03d.%03d.%03d.%03d' ${oldwg1ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" printf "%-33s" "$oldwg1city" - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg1slot${CClear}" + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg1slot${CClear}" else echo -en "${InvGreen} ${CClear}${CWhite} PUB WG IP ${CDkGray}[ ${CWhite}" printf '%03d.%03d.%03d.%03d' ${oldwg1ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" printf "%-33s" "$oldwg1city" - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg1slot${CClear}" + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg1slot${CClear}" fi if [ ${oldwg1txmbrate%.*} -lt 0 ]; then oldwg1txmbrate=0; oldwg1txmbratedisplay=0; fi - preparebar 79 "|" + preparebar 89 "|" progressbar $oldwg1txmbrate $MaxSpeedInet " Avg WG RX " "Mbps" "Standard" $oldwg1txmbratedisplay $MaxSpeedInet echo "" if [ ${oldwg1rxmbrate%.*} -lt 0 ]; then oldwg1rxmbrate=0; oldwg1rxmbratedisplay=0; fi - preparebar 79 "|" + preparebar 89 "|" progressbar $oldwg1rxmbrate $MaxSpeedInetUL " Avg WG TX " "Mbps" "Standard" $oldwg1rxmbratedisplay $MaxSpeedInetUL fi if [ "$wg2on" == "True" ]; then echo "" echo "" - echo -e "${InvDkGray}${CWhite} WG$wg2slot ${CClear}" + echo -e "${InvDkGray}${CWhite} WG$wg2slot ${CClear}" echo "" if [ "$oldwg2city" == "Private Network" ]; then echo -en "${InvGreen} ${CClear}${CWhite} PRV WG IP ${CDkGray}[ ${CWhite}" printf '%03d.%03d.%03d.%03d' ${oldwg2ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" printf "%-33s" "$oldwg2city" - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg2slot${CClear}" + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg2slot${CClear}" else echo -en "${InvGreen} ${CClear}${CWhite} PUB WG IP ${CDkGray}[ ${CWhite}" printf '%03d.%03d.%03d.%03d' ${oldwg2ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" printf "%-33s" "$oldwg2city" - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg2slot${CClear}" + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg2slot${CClear}" fi if [ ${oldwg2txmbrate%.*} -lt 0 ]; then oldwg2txmbrate=0; oldwg2txmbratedisplay=0; fi - preparebar 79 "|" + preparebar 89 "|" progressbar $oldwg2txmbrate $MaxSpeedInet " Avg WG RX " "Mbps" "Standard" $oldwg2txmbratedisplay $MaxSpeedInet echo "" if [ ${oldwg2rxmbrate%.*} -lt 0 ]; then oldwg2rxmbrate=0; oldwg2rxmbratedisplay=0; fi - preparebar 79 "|" + preparebar 89 "|" progressbar $oldwg2rxmbrate $MaxSpeedInetUL " Avg WG TX " "Mbps" "Standard" $oldwg2rxmbratedisplay $MaxSpeedInetUL fi if [ "$wg3on" == "True" ]; then echo "" echo "" - echo -e "${InvDkGray}${CWhite} WG$wg3slot ${CClear}" + echo -e "${InvDkGray}${CWhite} WG$wg3slot ${CClear}" echo "" if [ "$oldwg3city" == "Private Network" ]; then echo -en "${InvGreen} ${CClear}${CWhite} PRV WG IP ${CDkGray}[ ${CWhite}" printf '%03d.%03d.%03d.%03d' ${oldwg3ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" printf "%-33s" "$oldwg3city" - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg3slot${CClear}" + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg3slot${CClear}" else echo -en "${InvGreen} ${CClear}${CWhite} PUB WG IP ${CDkGray}[ ${CWhite}" printf '%03d.%03d.%03d.%03d' ${oldwg3ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" printf "%-33s" "$oldwg3city" - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg3slot${CClear}" + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg3slot${CClear}" fi if [ ${oldwg3txmbrate%.*} -lt 0 ]; then oldwg3txmbrate=0; oldwg3txmbratedisplay=0; fi - preparebar 79 "|" + preparebar 89 "|" progressbar $oldwg3txmbrate $MaxSpeedInet " Avg WG RX " "Mbps" "Standard" $oldwg3txmbratedisplay $MaxSpeedInet echo "" if [ ${oldwg3rxmbrate%.*} -lt 0 ]; then oldwg3rxmbrate=0; oldwg3rxmbratedisplay=0; fi - preparebar 79 "|" + preparebar 89 "|" progressbar $oldwg3rxmbrate $MaxSpeedInetUL " Avg WG TX " "Mbps" "Standard" $oldwg3rxmbratedisplay $MaxSpeedInetUL fi if [ "$wg4on" == "True" ]; then echo "" echo "" - echo -e "${InvDkGray}${CWhite} WG$wg4slot ${CClear}" + echo -e "${InvDkGray}${CWhite} WG$wg4slot ${CClear}" echo "" if [ "$oldwg4city" == "Private Network" ]; then echo -en "${InvGreen} ${CClear}${CWhite} PRV WG IP ${CDkGray}[ ${CWhite}" printf '%03d.%03d.%03d.%03d' ${oldwg4ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" printf "%-33s" "$oldwg4city" - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg4slot${CClear}" + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg4slot${CClear}" else echo -en "${InvGreen} ${CClear}${CWhite} PUB WG IP ${CDkGray}[ ${CWhite}" printf '%03d.%03d.%03d.%03d' ${oldwg4ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" printf "%-33s" "$oldwg4city" - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg4slot${CClear}" + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg4slot${CClear}" fi if [ ${oldwg4txmbrate%.*} -lt 0 ]; then oldwg4txmbrate=0; oldwg4txmbratedisplay=0; fi - preparebar 79 "|" + preparebar 89 "|" progressbar $oldwg4txmbrate $MaxSpeedInet " Avg WG RX " "Mbps" "Standard" $oldwg4txmbratedisplay $MaxSpeedInet echo "" if [ ${oldwg4rxmbrate%.*} -lt 0 ]; then oldwg4rxmbrate=0; oldwg4rxmbratedisplay=0; fi - preparebar 79 "|" + preparebar 89 "|" progressbar $oldwg4rxmbrate $MaxSpeedInetUL " Avg WG TX " "Mbps" "Standard" $oldwg4rxmbratedisplay $MaxSpeedInetUL fi if [ "$wg5on" == "True" ]; then echo "" echo "" - echo -e "${InvDkGray}${CWhite} WG$wg5slot ${CClear}" + echo -e "${InvDkGray}${CWhite} WG$wg5slot ${CClear}" echo "" if [ "$oldwg5city" == "Private Network" ]; then echo -en "${InvGreen} ${CClear}${CWhite} PRV WG IP ${CDkGray}[ ${CWhite}" printf '%03d.%03d.%03d.%03d' ${oldwg5ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" printf "%-33s" "$oldwg5city" - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg5slot${CClear}" + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg5slot${CClear}" else echo -en "${InvGreen} ${CClear}${CWhite} PUB WG IP ${CDkGray}[ ${CWhite}" printf '%03d.%03d.%03d.%03d' ${oldwg5ip//./ } - echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" + echo -en "${CDkGray} ] ${CWhite}CITY ${CDkGray}[ ${CWhite}" printf "%-33s" "$oldwg5city" - echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg5slot${CClear}" + echo -e "${CDkGray} ] ${InvDkGray}${CWhite}TUN: wgc$wg5slot${CClear}" fi if [ ${oldwg5txmbrate%.*} -lt 0 ]; then oldwg5txmbrate=0; oldwg5txmbratedisplay=0; fi - preparebar 79 "|" + preparebar 89 "|" progressbar $oldwg5txmbrate $MaxSpeedInet " Avg WG RX " "Mbps" "Standard" $oldwg5txmbratedisplay $MaxSpeedInet echo "" if [ ${oldwg5rxmbrate%.*} -lt 0 ]; then oldwg5rxmbrate=0; oldwg5rxmbratedisplay=0; fi - preparebar 79 "|" + preparebar 89 "|" progressbar $oldwg5rxmbrate $MaxSpeedInetUL " Avg WG TX " "Mbps" "Standard" $oldwg5rxmbratedisplay $MaxSpeedInetUL fi @@ -3212,70 +3216,70 @@ DisplayPage3() fi echo "" - echo -e "${InvDkGray}${CWhite} WiFi ${CClear}" + echo -e "${InvDkGray}${CWhite} WiFi ${CClear}" echo "" if [ "$MaxSpeed24GhzNow" != "0" ]; then if [ "$w24updown" == "UP" ]; then - echo -e "${InvGreen} ${CClear} ${CWhite}2.4GHz ${CDkGray}[ ${CWhite}Enabled - $w24udsched - UP ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname24${CClear}" + echo -e "${InvGreen} ${CClear} ${CWhite}2.4GHz ${CDkGray}[ ${CWhite}Enabled - $w24udsched - UP ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname24${CClear}" else - echo -e "${InvGreen} ${CClear} ${CWhite}2.4GHz ${CDkGray}[ ${CWhite}Enabled - $w24udsched - DOWN ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname24${CClear}" + echo -e "${InvGreen} ${CClear} ${CWhite}2.4GHz ${CDkGray}[ ${CWhite}Enabled - $w24udsched - DOWN ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname24${CClear}" fi - preparebar 79 "|" + preparebar 89 "|" progressbar $oldw24rxmbrate $MaxSpeed24GhzNow " Avg 24G RX" "Mbps" "Standard" $oldw24rxmbratedisplay $MaxSpeed24GhzNow echo "" - preparebar 79 "|" + preparebar 89 "|" progressbar $oldw24txmbrate $MaxSpeed24GhzNow " Avg 24G TX" "Mbps" "Standard" $oldw24txmbratedisplay $MaxSpeed24GhzNow echo "" - preparebar 79 "|" + preparebar 89 "|" converttemps $oldw24temp progressbar $currenttemp $currentrange " 2.4G Temp " $TempUnits "Standard" $currenttemp $currentrange else - echo -e "${InvRed} ${CClear}${CWhite} 2.4GHz ${CDkGray}[ ${CRed}Disabled ${CDkGray}]${CClear}" + echo -e "${InvRed} ${CClear}${CWhite} 2.4GHz ${CDkGray}[ ${CRed}Disabled ${CDkGray}]${CClear}" fi if [ "$MaxSpeed5GhzNow" != "0" ]; then echo "" echo "" if [ "$w5updown" == "UP" ]; then - echo -e "${InvGreen} ${CClear} ${CWhite}5.0GHz ${CDkGray}[ ${CWhite}Enabled - $w5udsched - UP ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname5${CClear}" + echo -e "${InvGreen} ${CClear} ${CWhite}5.0GHz ${CDkGray}[ ${CWhite}Enabled - $w5udsched - UP ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname5${CClear}" else - echo -e "${InvGreen} ${CClear} ${CWhite}5.0GHz ${CDkGray}[ ${CWhite}Enabled - $w5udsched - DOWN ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname5${CClear}" + echo -e "${InvGreen} ${CClear} ${CWhite}5.0GHz ${CDkGray}[ ${CWhite}Enabled - $w5udsched - DOWN ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname5${CClear}" fi - preparebar 79 "|" + preparebar 89 "|" progressbar $oldw5rxmbrate $MaxSpeed5GhzNow " Avg 5G1 RX" "Mbps" "Standard" $oldw5rxmbratedisplay $MaxSpeed5GhzNow echo "" - preparebar 79 "|" + preparebar 89 "|" progressbar $oldw5txmbrate $MaxSpeed5GhzNow " Avg 5G1 TX" "Mbps" "Standard" $oldw5txmbratedisplay $MaxSpeed5GhzNow echo "" - preparebar 79 "|" + preparebar 89 "|" converttemps $oldw5temp progressbar $currenttemp $currentrange " 5G-1 Temp " $TempUnits "Standard" $currenttemp $currentrange else echo "" echo "" - echo -e "${InvRed} ${CClear}${CWhite} 5.0GHz ${CDkGray}[ ${CRed}Disabled ${CDkGray}]${CClear}" + echo -e "${InvRed} ${CClear}${CWhite} 5.0GHz ${CDkGray}[ ${CRed}Disabled ${CDkGray}]${CClear}" fi if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then if [ "$MaxSpeed52GhzNow" != "0" ]; then echo "" echo "" if [ "$w52updown" == "UP" ]; then - echo -e "${InvGreen} ${CClear} ${CWhite}5.0GHz (2) ${CDkGray}[ ${CWhite}Enabled - $w52udsched - UP ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname52${CClear}" + echo -e "${InvGreen} ${CClear} ${CWhite}5.0GHz (2) ${CDkGray}[ ${CWhite}Enabled - $w52udsched - UP ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname52${CClear}" else - echo -e "${InvGreen} ${CClear} ${CWhite}5.0GHz (2) ${CDkGray}[ ${CWhite}Enabled - $w52udsched - DOWN ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname52${CClear}" + echo -e "${InvGreen} ${CClear} ${CWhite}5.0GHz (2) ${CDkGray}[ ${CWhite}Enabled - $w52udsched - DOWN ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname52${CClear}" fi - preparebar 79 "|" + preparebar 89 "|" progressbar $oldw52rxmbrate $MaxSpeed5GhzNow " Avg 5G2 RX" "Mbps" "Standard" $oldw52rxmbratedisplay $MaxSpeed5GhzNow echo "" - preparebar 79 "|" + preparebar 89 "|" progressbar $oldw52txmbrate $MaxSpeed5GhzNow " Avg 5G2 TX" "Mbps" "Standard" $oldw52txmbratedisplay $MaxSpeed5GhzNow echo "" - preparebar 79 "|" + preparebar 89 "|" converttemps $oldw52temp progressbar $currenttemp $currentrange " 5G-2 Temp " $TempUnits "Standard" $currenttemp $currentrange else echo "" echo "" - echo -e "${InvRed} ${CClear}${CWhite} 5.0GHz (2) ${CDkGray}[ ${CRed}Disabled ${CDkGray}]${CClear}" + echo -e "${InvRed} ${CClear}${CWhite} 5.0GHz (2) ${CDkGray}[ ${CRed}Disabled ${CDkGray}]${CClear}" fi fi if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then @@ -3283,23 +3287,23 @@ DisplayPage3() echo "" echo "" if [ "$w6updown" == "UP" ]; then - echo -e "${InvGreen} ${CClear} ${CWhite}6.0GHz ${CDkGray}[ ${CWhite}Enabled - $w6udsched - UP ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname6${CClear}" + echo -e "${InvGreen} ${CClear} ${CWhite}6.0GHz ${CDkGray}[ ${CWhite}Enabled - $w6udsched - UP ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname6${CClear}" else - echo -e "${InvGreen} ${CClear} ${CWhite}6.0GHz ${CDkGray}[ ${CWhite}Enabled - $w6udsched - DOWN ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname6${CClear}" + echo -e "${InvGreen} ${CClear} ${CWhite}6.0GHz ${CDkGray}[ ${CWhite}Enabled - $w6udsched - DOWN ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname6${CClear}" fi - preparebar 79 "|" + preparebar 89 "|" progressbar $oldw6rxmbrate $MaxSpeed6GhzNow " Avg 60G RX" "Mbps" "Standard" $oldw6rxmbratedisplay $MaxSpeed6GhzNow echo "" - preparebar 79 "|" + preparebar 89 "|" progressbar $oldw6txmbrate $MaxSpeed6GhzNow " Avg 60G TX" "Mbps" "Standard" $oldw6txmbratedisplay $MaxSpeed6GhzNow echo "" - preparebar 79 "|" + preparebar 89 "|" converttemps $oldw6temp progressbar $currenttemp $currentrange " 6.0G Temp " $TempUnits "Standard" $currenttemp $currentrange else echo "" echo "" - echo -e "${InvRed} ${CClear}${CWhite} 6.0GHz ${CDkGray}[ ${CRed}Disabled ${CDkGray}]${CClear}" + echo -e "${InvRed} ${CClear}${CWhite} 6.0GHz ${CDkGray}[ ${CRed}Disabled ${CDkGray}]${CClear}" fi fi if [ "$FourBandCustom56624" == "True" ]; then @@ -3307,23 +3311,23 @@ DisplayPage3() echo "" echo "" if [ "$w62updown" == "UP" ]; then - echo -e "${InvGreen} ${CClear} ${CWhite}6.0GHz (2) ${CDkGray}[ ${CWhite}Enabled - $w62udsched - UP ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname62${CClear}" + echo -e "${InvGreen} ${CClear} ${CWhite}6.0GHz (2) ${CDkGray}[ ${CWhite}Enabled - $w62udsched - UP ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname62${CClear}" else - echo -e "${InvGreen} ${CClear} ${CWhite}6.0GHz (2) ${CDkGray}[ ${CWhite}Enabled - $w62udsched - DOWN ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname62${CClear}" + echo -e "${InvGreen} ${CClear} ${CWhite}6.0GHz (2) ${CDkGray}[ ${CWhite}Enabled - $w62udsched - DOWN ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname62${CClear}" fi - preparebar 79 "|" + preparebar 89 "|" progressbar $oldw62rxmbrate $MaxSpeed62GhzNow " Avg 6G2 RX" "Mbps" "Standard" $oldw62rxmbratedisplay $MaxSpeed62GhzNow echo "" - preparebar 79 "|" + preparebar 89 "|" progressbar $oldw62txmbrate $MaxSpeed62GhzNow " Avg 6G2 TX" "Mbps" "Standard" $oldw62txmbratedisplay $MaxSpeed62GhzNow echo "" - preparebar 79 "|" + preparebar 89 "|" converttemps $oldw62temp progressbar $currenttemp $currentrange " 6G-2 Temp " $TempUnits "Standard" $currenttemp $currentrange else echo "" echo "" - echo -e "${InvRed} ${CClear}${CWhite} 6.0GHz (2) ${CDkGray}[ ${CRed}Disabled ${CDkGray}]${CClear}" + echo -e "${InvRed} ${CClear}${CWhite} 6.0GHz (2) ${CDkGray}[ ${CRed}Disabled ${CDkGray}]${CClear}" fi fi } @@ -3339,7 +3343,7 @@ DisplayPage4() fi showheader echo "" - echo -e "${InvDkGray}${CWhite} Speedtest ${CClear}" + echo -e "${InvDkGray}${CWhite} Speedtest ${CClear}" if [ "$QueueVPNSlot1" = "1" ]; then DisplaySpdtst 1 @@ -3644,17 +3648,17 @@ DisplaySpdtst() fi if { [ "$vpn1on" = "True" ] || [ "$vpn2on" = "True" ] || [ "$vpn3on" = "True" ] || [ "$vpn4on" = "True" ] || [ "$vpn5on" = "True" ]; } && { [ "$wg1on" = "True" ] || [ "$wg2on" = "True" ] || [ "$wg3on" = "True" ] || [ "$wg4on" = "True" ] || [ "$wg5on" = "True" ]; }; then - printf "\r${InvGreen} ${CClear} ${CGreen}(I)${CWhite}nitiate WAN Speedtest on: ${CGreen}$WANIFNAME ${CWhite}| VPN 1:${CGreen}(1) ${CWhite}2:${CGreen}(2) ${CWhite}3:${CGreen}(3) ${CWhite}4:${CGreen}(4) ${CWhite}5:${CGreen}(5) ${CWhite} | WG 1:${CGreen}(6) ${CWhite}2:${CGreen}(7) ${CWhite}3:${CGreen}(8) ${CWhite}4:${CGreen}(9) ${CWhite}5:${CGreen}(0)${CClear}" + printf "\r${InvGreen} ${CClear} ${CGreen}(I)${CWhite}nitiate WAN Speedtest on: ${CGreen}$WANIFNAME ${CWhite}| VPN 1:${CGreen}(1) ${CWhite}2:${CGreen}(2) ${CWhite}3:${CGreen}(3) ${CWhite}4:${CGreen}(4) ${CWhite}5:${CGreen}(5) ${CWhite} | WG 1:${CGreen}(6) ${CWhite}2:${CGreen}(7) ${CWhite}3:${CGreen}(8) ${CWhite}4:${CGreen}(9) ${CWhite}5:${CGreen}(0)${CClear}" elif [ "$vpn1on" = "True" ] || [ "$vpn2on" = "True" ] || [ "$vpn3on" = "True" ] || [ "$vpn4on" = "True" ] || [ "$vpn5on" = "True" ]; then - printf "\r${InvGreen} ${CClear} ${CGreen}(I)${CWhite}nitiate WAN Speedtest on: ${CGreen}$WANIFNAME ${CWhite}| VPN 1:${CGreen}(1) ${CWhite}2:${CGreen}(2) ${CWhite}3:${CGreen}(3) ${CWhite}4:${CGreen}(4) ${CWhite}5:${CGreen}(5) ${CWhite} | ${CDkGray}WG 1:(6) 2:(7) 3:(8) 4:(9) 5:(0)${CClear}" + printf "\r${InvGreen} ${CClear} ${CGreen}(I)${CWhite}nitiate WAN Speedtest on: ${CGreen}$WANIFNAME ${CWhite}| VPN 1:${CGreen}(1) ${CWhite}2:${CGreen}(2) ${CWhite}3:${CGreen}(3) ${CWhite}4:${CGreen}(4) ${CWhite}5:${CGreen}(5) ${CWhite} | ${CDkGray}WG 1:(6) 2:(7) 3:(8) 4:(9) 5:(0)${CClear}" elif [ "$wg1on" = "True" ] || [ "$wg2on" = "True" ] || [ "$wg3on" = "True" ] || [ "$wg4on" = "True" ] || [ "$wg5on" = "True" ]; then - printf "\r${InvGreen} ${CClear} ${CGreen}(I)${CWhite}nitiate WAN Speedtest on: ${CGreen}$WANIFNAME ${CWhite}| ${CDkGray}VPN 1:(1) 2:(2) 3:(3) 4:(4) 5:(5) ${CWhite} | WG 1:${CGreen}(6) ${CWhite}2:${CGreen}(7) ${CWhite}3:${CGreen}(8) ${CWhite}4:${CGreen}(9) ${CWhite}5:${CGreen}(0)${CClear}" + printf "\r${InvGreen} ${CClear} ${CGreen}(I)${CWhite}nitiate WAN Speedtest on: ${CGreen}$WANIFNAME ${CWhite}| ${CDkGray}VPN 1:(1) 2:(2) 3:(3) 4:(4) 5:(5) ${CWhite} | WG 1:${CGreen}(6) ${CWhite}2:${CGreen}(7) ${CWhite}3:${CGreen}(8) ${CWhite}4:${CGreen}(9) ${CWhite}5:${CGreen}(0)${CClear}" else printf "\r${InvGreen} ${CClear} ${CGreen}(I)${CWhite}nitiate WAN Speedtest${CClear} " fi echo "" - echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}------------------------------------------------------------------------------------------------------------------------${CClear}" echo "" echo -e "${InvGreen} ${CClear} ${CWhite}Test Date ${CDkGray}[ ${CGreen}$SpdDate${CClear}" echo -e "${InvGreen} ${CClear} ${CWhite}Server ${CDkGray}[ ${CGreen}$SpdServer${CClear}" @@ -3671,10 +3675,10 @@ DisplaySpdtst() echo -e "${InvGreen} ${CClear} ${CCyan}Upload ${CDkGray}[ ${CGreen}$SpdUpload (Mbps)${CWhite} | Jitter: ${CGreen}$SpdULLatencyJt (ms)${CClear}" echo -e "${InvGreen} ${CClear} ${CDkGray} [ ${CWhite}Latency: ${CGreen}$SpdULLatency (ms)${CWhite} | Latency Low: ${CGreen}$SpdULLatencyLo (ms) ${CWhite}| High: ${CGreen}$SpdULLatencyHi (ms)${CClear}" echo "" - preparebar 79 "|" + preparebar 89 "|" progressbar $SpdDownload $MaxSpeedInet " DL vs WAN " "Mbps" "Reverse" $SpdDownload $MaxSpeedInet echo "" - preparebar 79 "|" + preparebar 89 "|" progressbar $SpdUpload $MaxSpeedInetUL " UL vs WAN " "Mbps" "Reverse" $SpdUpload $MaxSpeedInetUL } @@ -3713,10 +3717,10 @@ DisplayPage5() fi showheader echo "" - echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} Network Diagnostics ${CClear}" + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} Network Diagnostics ${CClear}" echo -e "${InvGreen} ${CClear}" echo -e "${InvGreen} ${CClear} ${CWhite}Run ${CGreen}(D)${CWhite}iagnostics | Last Run Date/Time: ${CGreen}$Lastruntime" - echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}------------------------------------------------------------------------------------------------------------------------${CClear}" echo "" if [ "$QueueNetworkDiag" = "1" ] @@ -3807,48 +3811,48 @@ DisplayPage5() fi echo "" - printf "${InvYellow} ${CClear} ${CWhite}SSL Handshake Test... ${CYellow}[Checking] ${CDkGray}| nc -w3 8.8.8.8 443 && echo | openssl s_client -connect 8.8.8.8:443>${CClear}" + printf "${InvYellow} ${CClear} ${CWhite}SSL Handshake Test... ${CYellow}[Checking] ${CDkGray}| nc -w3 8.8.8.8 443 && echo | openssl s_client -connect 8.8.8.8:443 | awk 'ha>${CClear}" SSL_STATE="$(nc -w3 8.8.8.8 443 >/dev/null 2>&1 && echo | openssl s_client -connect 8.8.8.8:443 >/dev/null 2>&1 | awk 'handshake && $1 == "Verification" { if ($2=="OK") exit; exit 1 } $1 $2 == "SSLhandshake" { handshake = 1 }' >/dev/null 2>&1; echo $?)" sleep 1 if [ "$SSL_STATE" = "0" ]; then - printf "\r${InvGreen} ${CClear} ${CWhite}SSL Handshake Test... ${CGreen}[Passed] ${CDkGray}| nc -w3 8.8.8.8 443 && echo | openssl s_client -connect 8.8.8.8:443>${CClear}" + printf "\r${InvGreen} ${CClear} ${CWhite}SSL Handshake Test... ${CGreen}[Passed] ${CDkGray}| nc -w3 8.8.8.8 443 && echo | openssl s_client -connect 8.8.8.8:443 | awk 'ha>${CClear}" SSLHandshakeTest="Passed" else - printf "\r${InvRed} ${CClear} ${CWhite}SSL Handshake Test... ${CRed}[Failed] ${CDkGray}| nc -w3 8.8.8.8 443 && echo | openssl s_client -connect 8.8.8.8:443>${CClear}" + printf "\r${InvRed} ${CClear} ${CWhite}SSL Handshake Test... ${CRed}[Failed] ${CDkGray}| nc -w3 8.8.8.8 443 && echo | openssl s_client -connect 8.8.8.8:443 | awk 'ha>${CClear}" SSLHandshakeTest="Failed" fi echo "" echo "" - echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} NMAP Port Scan Results ${CClear}" + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} NMAP Port Scan Results ${CClear}" if [ "$PSView" == "TCP" ]; then echo -e "${InvGreen} ${CClear}" echo -e "${InvGreen} ${CClear}${CWhite} Show Open ${InvDkGray} ${CGreen}(T)${CWhite}CP ${CClear}${CWhite} Ports | Show Open ${CGreen}(U)${CWhite}DP Ports${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}------------------------------------------------------------------------------------------------------------------------${CClear}" echo "" if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then echo -e "${InvGreen} ${CClear} ${CWhite}WAN0 IP: ${CGreen}$oldwan0ip${CClear}" - WANnmap=$(nmap $oldwan0ip | grep "open") - if [ -z "$WANnmap" ]; then echo "None"; else nmap $oldwan0ip | grep "open"; fi + WANnmap=$(nmap $oldwan0ip | grep "open" | sed 's/^/ /') + if [ -z "$WANnmap" ]; then echo "None"; else nmap $oldwan0ip | grep "open" | sed 's/^/ /'; fi echo "" fi echo -e "${InvGreen} ${CClear} ${CWhite}BR0 IP: ${CGreen}$oldlanip${CClear}" - LANnmap=$(nmap $oldlanip | grep "open") - if [ -z "$LANnmap" ]; then echo "None"; else nmap $oldlanip | grep "open"; fi + LANnmap=$(nmap $oldlanip | grep "open" | sed 's/^/ /') + if [ -z "$LANnmap" ]; then echo "None"; else nmap $oldlanip | grep "open" | sed 's/^/ /'; fi elif [ "$PSView" == "UDP" ]; then echo -e "${InvGreen} ${CClear}" echo -e "${InvGreen} ${CClear}${CWhite} Show Open ${CGreen}(T)${CWhite}CP Ports | Show Open ${InvDkGray} ${CGreen}(U)${CWhite}DP ${CClear}${CWhite} Ports${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}------------------------------------------------------------------------------------------------------------------------${CClear}" echo "" if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then echo -e "${InvGreen} ${CClear} ${CWhite}WAN0 IP: ${CGreen}$oldwan0ip${CClear}" - WANUnmap=$(nmap -sU $oldwan0ip | grep "open") - if [ -z "$WANUnmap" ]; then echo "None"; else nmap -sU $oldwan0ip | grep "open"; fi + WANUnmap=$(nmap -sU $oldwan0ip | grep "open" | sed 's/^/ /') + if [ -z "$WANUnmap" ]; then echo "None"; else nmap -sU $oldwan0ip | grep "open" | sed 's/^/ /'; fi echo "" fi echo -e "${InvGreen} ${CClear} ${CWhite}BR0 IP: ${CGreen}$oldlanip${CClear}" - LANUnmap=$(nmap -sU $oldlanip | grep "open") - if [ -z "$LANUnmap" ]; then echo "None"; else nmap -sU $oldlanip | grep "open"; fi + LANUnmap=$(nmap -sU $oldlanip | grep "open" | sed 's/^/ /') + if [ -z "$LANUnmap" ]; then echo "None"; else nmap -sU $oldlanip | grep "open" | sed 's/^/ /'; fi fi { echo 'Lastruntime="'"$(date)"'"' @@ -3918,18 +3922,18 @@ else fi echo "" if [ "$SSLHandshakeTest" == "Passed" ]; then - printf "\r${InvGreen} ${CClear} ${CWhite}SSL Handshake Test... ${CGreen}[Passed] ${CDkGray}| nc -w3 8.8.8.8 443 && echo | openssl s_client -connect 8.8.8.8:443>${CClear}" + printf "\r${InvGreen} ${CClear} ${CWhite}SSL Handshake Test... ${CGreen}[Passed] ${CDkGray}| nc -w3 8.8.8.8 443 && echo | openssl s_client -connect 8.8.8.8:443 | awk 'ha>${CClear}" else - printf "\r${InvRed} ${CClear} ${CWhite}SSL Handshake Test... ${CRed}[Failed] ${CDkGray}| nc -w3 8.8.8.8 443 && echo | openssl s_client -connect 8.8.8.8:443>${CClear}" + printf "\r${InvRed} ${CClear} ${CWhite}SSL Handshake Test... ${CRed}[Failed] ${CDkGray}| nc -w3 8.8.8.8 443 && echo | openssl s_client -connect 8.8.8.8:443 | awk 'ha>${CClear}" fi echo "" echo "" - echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} NMAP Port Scan Results ${CClear}" + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} NMAP Port Scan Results ${CClear}" if [ "$PSView" == "TCP" ]; then echo -e "${InvGreen} ${CClear}" echo -e "${InvGreen} ${CClear}${CWhite} Show Open ${InvDkGray} ${CGreen}(T)${CWhite}CP ${CClear}${CWhite} Ports | Show Open ${CGreen}(U)${CWhite}DP Ports${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}------------------------------------------------------------------------------------------------------------------------${CClear}" echo "" if [ "$ScreenshotMode" == "1" ]; then oldwan0ip="12.34.56.78" #demo @@ -3939,8 +3943,8 @@ else if [ ! -f $NMAPWANRESPATH ]; then echo "None" else - WANnmap=$(cat $NMAPWANRESPATH | grep "open") - if [ -z "$WANnmap" ]; then echo "None"; else cat $NMAPWANRESPATH | grep "open"; fi + WANnmap=$(cat $NMAPWANRESPATH | grep "open" | sed 's/^/ /') + if [ -z "$WANnmap" ]; then echo "None"; else cat $NMAPWANRESPATH | grep "open" | sed 's/^/ /'; fi fi echo "" fi @@ -3948,21 +3952,21 @@ else if [ ! -f $NMAPLANRESPATH ]; then echo "None" else - LANnmap=$(cat $NMAPLANRESPATH | grep "open") - if [ -z "$LANnmap" ]; then echo "None"; else cat $NMAPLANRESPATH | grep "open"; fi + LANnmap=$(cat $NMAPLANRESPATH | grep "open" | sed 's/^/ /') + if [ -z "$LANnmap" ]; then echo "None"; else cat $NMAPLANRESPATH | grep "open" | sed 's/^/ /'; fi fi elif [ "$PSView" == "UDP" ]; then echo -e "${InvGreen} ${CClear}" echo -e "${InvGreen} ${CClear}${CWhite} Show Open ${CGreen}(T)${CWhite}CP Ports | Show Open ${InvDkGray} ${CGreen}(U)${CWhite}DP ${CClear}${CWhite} Ports${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}------------------------------------------------------------------------------------------------------------------------${CClear}" echo "" if [ "$WAN0AltModes" == "0" ] || [ "$OpsMode" == "1" ]; then echo -e "${InvGreen} ${CClear} ${CWhite}WAN0 IP: ${CGreen}$oldwan0ip${CClear}" if [ ! -f $NMAPUWANRESPATH ]; then echo "None" else - WANUnmap=$(cat $NMAPUWANRESPATH | grep "open") - if [ -z "$WANUnmap" ]; then echo "None"; else cat $NMAPUWANRESPATH | grep "open"; fi + WANUnmap=$(cat $NMAPUWANRESPATH | grep "open" | sed 's/^/ /') + if [ -z "$WANUnmap" ]; then echo "None"; else cat $NMAPUWANRESPATH | grep "open" | sed 's/^/ /'; fi fi echo "" fi @@ -3970,8 +3974,8 @@ else if [ ! -f $NMAPULANRESPATH ]; then echo "None" else - LANUnmap=$(cat $NMAPULANRESPATH | grep "open") - if [ -z "$LANUnmap" ]; then echo "None"; else cat $NMAPULANRESPATH | grep "open"; fi + LANUnmap=$(cat $NMAPULANRESPATH | grep "open" | sed 's/^/ /') + if [ -z "$LANUnmap" ]; then echo "None"; else cat $NMAPULANRESPATH | grep "open" | sed 's/^/ /'; fi fi fi fi @@ -3988,7 +3992,7 @@ DisplayPage6() fi showheader echo "" - echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} Top 10 Network Connections/Bandwidth Stats ${CClear}" + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} Top 10 Network Connections/Bandwidth Stats ${CClear}" echo -e "${InvGreen} ${CClear}" if [ "$QueueNetworkConn" = "1" ] @@ -4102,9 +4106,9 @@ DisplayPage6() echo -e "${InvGreen} ${CClear}${CWhite} View ${InvDkGray} ${CGreen}(W)${CWhite}AN ${CClear}${CWhite} | ${CGreen}(L)${CWhite}AN${CClear}" fi - echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}------------------------------------------------------------------------------------------------------------------------${CClear}" echo "" - echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} WAN ${CClear}" + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} WAN ${CClear}" wansegments1=$(cat /jffs/addons/rtrmon.d/wanresult.txt 2>&1 | awk 'NR==7 {print $1, $2, $4} NR==8 {print $1, $3}') @@ -4187,45 +4191,45 @@ DisplayPage6() in10="$(echo $wansegments10 | awk '{print $5}')" if [ "$line1" == "1" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line1 $dest1 <=> $src1" " Out: $out1 | In: $in1" + printf "${CWhite}%-92s${CGreen}%s\n" " $line1 $dest1 <=> $src1" " Out: $out1 | In: $in1" else echo "No Data" fi if [ "$line2" == "2" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line2 $dest2 <=> $src2" " Out: $out2 | In: $in2" + printf "${CWhite}%-92s${CGreen}%s\n" " $line2 $dest2 <=> $src2" " Out: $out2 | In: $in2" fi if [ "$line3" == "3" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line3 $dest3 <=> $src3" " Out: $out3 | In: $in3" + printf "${CWhite}%-92s${CGreen}%s\n" " $line3 $dest3 <=> $src3" " Out: $out3 | In: $in3" fi if [ "$line4" == "4" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line4 $dest4 <=> $src4" " Out: $out4 | In: $in4" + printf "${CWhite}%-92s${CGreen}%s\n" " $line4 $dest4 <=> $src4" " Out: $out4 | In: $in4" fi if [ "$line5" == "5" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line5 $dest5 <=> $src5" " Out: $out5 | In: $in5" + printf "${CWhite}%-92s${CGreen}%s\n" " $line5 $dest5 <=> $src5" " Out: $out5 | In: $in5" fi if [ "$line6" == "6" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line6 $dest6 <=> $src6" " Out: $out6 | In: $in6" + printf "${CWhite}%-92s${CGreen}%s\n" " $line6 $dest6 <=> $src6" " Out: $out6 | In: $in6" fi if [ "$line7" == "7" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line7 $dest7 <=> $src7" " Out: $out7 | In: $in7" + printf "${CWhite}%-92s${CGreen}%s\n" " $line7 $dest7 <=> $src7" " Out: $out7 | In: $in7" fi if [ "$line8" == "8" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line8 $dest8 <=> $src8" " Out: $out8 | In: $in8" + printf "${CWhite}%-92s${CGreen}%s\n" " $line8 $dest8 <=> $src8" " Out: $out8 | In: $in8" fi if [ "$line9" == "9" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line9 $dest9 <=> $src9" " Out: $out9 | In: $in9" + printf "${CWhite}%-92s${CGreen}%s\n" " $line9 $dest9 <=> $src9" " Out: $out9 | In: $in9" fi if [ "$line10" == "10" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" "$line10 $dest10 <=> $src10" " Out: $out10 | In: $in10" + printf "${CWhite}%-92s${CGreen}%s\n" "$line10 $dest10 <=> $src10" " Out: $out10 | In: $in10" fi fi @@ -4238,10 +4242,10 @@ DisplayPage6() echo -e "${InvGreen} ${CClear}${CWhite} View ${CGreen}(W)${CWhite}AN | ${InvDkGray} ${CGreen}(L)${CWhite}AN ${CClear}" fi - echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}------------------------------------------------------------------------------------------------------------------------${CClear}" echo "" - echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} LAN ${CClear}" + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} LAN ${CClear}" lansegments1=$(cat /jffs/addons/rtrmon.d/lanresult.txt 2>&1 | awk 'NR==7 {print $1, $2, $4} NR==8 {print $1, $3}') @@ -4324,45 +4328,45 @@ DisplayPage6() in10="$(echo $lansegments10 | awk '{print $5}')" if [ "$line1" == "1" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line1 $dest1 <=> $src1" " Out: $out1 | In: $in1" + printf "${CWhite}%-92s${CGreen}%s\n" " $line1 $dest1 <=> $src1" " Out: $out1 | In: $in1" else echo "No Data" fi if [ "$line2" == "2" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line2 $dest2 <=> $src2" " Out: $out2 | In: $in2" + printf "${CWhite}%-92s${CGreen}%s\n" " $line2 $dest2 <=> $src2" " Out: $out2 | In: $in2" fi if [ "$line3" == "3" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line3 $dest3 <=> $src3" " Out: $out3 | In: $in3" + printf "${CWhite}%-92s${CGreen}%s\n" " $line3 $dest3 <=> $src3" " Out: $out3 | In: $in3" fi if [ "$line4" == "4" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line4 $dest4 <=> $src4" " Out: $out4 | In: $in4" + printf "${CWhite}%-92s${CGreen}%s\n" " $line4 $dest4 <=> $src4" " Out: $out4 | In: $in4" fi if [ "$line5" == "5" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line5 $dest5 <=> $src5" " Out: $out5 | In: $in5" + printf "${CWhite}%-92s${CGreen}%s\n" " $line5 $dest5 <=> $src5" " Out: $out5 | In: $in5" fi if [ "$line6" == "6" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line6 $dest6 <=> $src6" " Out: $out6 | In: $in6" + printf "${CWhite}%-92s${CGreen}%s\n" " $line6 $dest6 <=> $src6" " Out: $out6 | In: $in6" fi if [ "$line7" == "7" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line7 $dest7 <=> $src7" " Out: $out7 | In: $in7" + printf "${CWhite}%-92s${CGreen}%s\n" " $line7 $dest7 <=> $src7" " Out: $out7 | In: $in7" fi if [ "$line8" == "8" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line8 $dest8 <=> $src8" " Out: $out8 | In: $in8" + printf "${CWhite}%-92s${CGreen}%s\n" " $line8 $dest8 <=> $src8" " Out: $out8 | In: $in8" fi if [ "$line9" == "9" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line9 $dest9 <=> $src9" " Out: $out9 | In: $in9" + printf "${CWhite}%-92s${CGreen}%s\n" " $line9 $dest9 <=> $src9" " Out: $out9 | In: $in9" fi if [ "$line10" == "10" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" "$line10 $dest10 <=> $src10" " Out: $out10 | In: $in10" + printf "${CWhite}%-92s${CGreen}%s\n" "$line10 $dest10 <=> $src10" " Out: $out10 | In: $in10" fi fi @@ -4371,7 +4375,7 @@ DisplayPage6() if [ "$vpn1on" == "True" ] || [ "$vpn2on" == "True" ] || [ "$vpn3on" == "True" ] || [ "$vpn4on" == "True" ] || [ "$vpn5on" == "True" ] || [ "$wg1on" == "True" ] || [ "$wg2on" == "True" ] || [ "$wg3on" == "True" ] || [ "$wg4on" == "True" ] || [ "$wg5on" == "True" ]; then echo -e "${InvGreen} ${CClear}" echo -e "${InvGreen} ${CClear}${CWhite} View ${CGreen}(W)${CWhite}AN ${CWhite}| ${CGreen}(L)${CWhite}AN | ${InvDkGray} ${CGreen}(V)${CWhite}PN ${CClear} ${CWhite}| W${CGreen}(G)${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}------------------------------------------------------------------------------------------------------------------------${CClear}" echo "" slot=0 @@ -4382,7 +4386,7 @@ DisplayPage6() eval selectedslot="\$${selectedslot}" if [ "$selectedslot" = "True" ] && [ "$VPNSite2Site" = "0" ] then - echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} VPN$slot ${CClear}" + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} VPN$slot ${CClear}" vpnsegments1=$(cat /jffs/addons/rtrmon.d/vpn${slot}result.txt 2>&1 | awk 'NR==7 {print $1, $2, $4} NR==8 {print $1, $3}') @@ -4465,45 +4469,45 @@ DisplayPage6() in10="$(echo $vpnsegments10 | awk '{print $5}')" if [ "$line1" == "1" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line1 $dest1 <=> $src1" " Out: $out1 | In: $in1" + printf "${CWhite}%-92s${CGreen}%s\n" " $line1 $dest1 <=> $src1" " Out: $out1 | In: $in1" else echo "No Data" fi if [ "$line2" == "2" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line2 $dest2 <=> $src2" " Out: $out2 | In: $in2" + printf "${CWhite}%-92s${CGreen}%s\n" " $line2 $dest2 <=> $src2" " Out: $out2 | In: $in2" fi if [ "$line3" == "3" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line3 $dest3 <=> $src3" " Out: $out3 | In: $in3" + printf "${CWhite}%-92s${CGreen}%s\n" " $line3 $dest3 <=> $src3" " Out: $out3 | In: $in3" fi if [ "$line4" == "4" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line4 $dest4 <=> $src4" " Out: $out4 | In: $in4" + printf "${CWhite}%-92s${CGreen}%s\n" " $line4 $dest4 <=> $src4" " Out: $out4 | In: $in4" fi if [ "$line5" == "5" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line5 $dest5 <=> $src5" " Out: $out5 | In: $in5" + printf "${CWhite}%-92s${CGreen}%s\n" " $line5 $dest5 <=> $src5" " Out: $out5 | In: $in5" fi if [ "$line6" == "6" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line6 $dest6 <=> $src6" " Out: $out6 | In: $in6" + printf "${CWhite}%-92s${CGreen}%s\n" " $line6 $dest6 <=> $src6" " Out: $out6 | In: $in6" fi if [ "$line7" == "7" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line7 $dest7 <=> $src7" " Out: $out7 | In: $in7" + printf "${CWhite}%-92s${CGreen}%s\n" " $line7 $dest7 <=> $src7" " Out: $out7 | In: $in7" fi if [ "$line8" == "8" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line8 $dest8 <=> $src8" " Out: $out8 | In: $in8" + printf "${CWhite}%-92s${CGreen}%s\n" " $line8 $dest8 <=> $src8" " Out: $out8 | In: $in8" fi if [ "$line9" == "9" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line9 $dest9 <=> $src9" " Out: $out9 | In: $in9" + printf "${CWhite}%-92s${CGreen}%s\n" " $line9 $dest9 <=> $src9" " Out: $out9 | In: $in9" fi if [ "$line10" == "10" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" "$line10 $dest10 <=> $src10" " Out: $out10 | In: $in10" + printf "${CWhite}%-92s${CGreen}%s\n" "$line10 $dest10 <=> $src10" " Out: $out10 | In: $in10" fi echo "" @@ -4517,7 +4521,7 @@ if [ "$NCView" = "WG" ] if [ "$vpn1on" == "True" ] || [ "$vpn2on" == "True" ] || [ "$vpn3on" == "True" ] || [ "$vpn4on" == "True" ] || [ "$vpn5on" == "True" ] || [ "$wg1on" == "True" ] || [ "$wg2on" == "True" ] || [ "$wg3on" == "True" ] || [ "$wg4on" == "True" ] || [ "$wg5on" == "True" ]; then echo -e "${InvGreen} ${CClear}" echo -e "${InvGreen} ${CClear}${CWhite} View ${CGreen}(W)${CWhite}AN ${CWhite}| ${CGreen}(L)${CWhite}AN | ${CGreen}(V)${CWhite}PN | ${InvDkGray} W${CGreen}(G) ${CClear}" - echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" + echo -e "${InvGreen} ${CClear}${CDkGray}------------------------------------------------------------------------------------------------------------------------${CClear}" echo "" slot=0 @@ -4528,7 +4532,7 @@ if [ "$NCView" = "WG" ] eval selectedslot="\$${selectedslot}" if [ "$selectedslot" = "True" ] && [ "$VPNSite2Site" = "0" ] then - echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} WG$slot ${CClear}" + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} WG$slot ${CClear}" wgsegments1=$(cat /jffs/addons/rtrmon.d/wgc${slot}result.txt 2>&1 | awk 'NR==7 {print $1, $2, $4} NR==8 {print $1, $3}') @@ -4611,45 +4615,45 @@ if [ "$NCView" = "WG" ] in10="$(echo $wgsegments10 | awk '{print $5}')" if [ "$line1" == "1" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line1 $dest1 <=> $src1" " Out: $out1 | In: $in1" + printf "${CWhite}%-92s${CGreen}%s\n" " $line1 $dest1 <=> $src1" " Out: $out1 | In: $in1" else echo "No Data" fi if [ "$line2" == "2" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line2 $dest2 <=> $src2" " Out: $out2 | In: $in2" + printf "${CWhite}%-92s${CGreen}%s\n" " $line2 $dest2 <=> $src2" " Out: $out2 | In: $in2" fi if [ "$line3" == "3" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line3 $dest3 <=> $src3" " Out: $out3 | In: $in3" + printf "${CWhite}%-92s${CGreen}%s\n" " $line3 $dest3 <=> $src3" " Out: $out3 | In: $in3" fi if [ "$line4" == "4" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line4 $dest4 <=> $src4" " Out: $out4 | In: $in4" + printf "${CWhite}%-92s${CGreen}%s\n" " $line4 $dest4 <=> $src4" " Out: $out4 | In: $in4" fi if [ "$line5" == "5" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line5 $dest5 <=> $src5" " Out: $out5 | In: $in5" + printf "${CWhite}%-92s${CGreen}%s\n" " $line5 $dest5 <=> $src5" " Out: $out5 | In: $in5" fi if [ "$line6" == "6" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line6 $dest6 <=> $src6" " Out: $out6 | In: $in6" + printf "${CWhite}%-92s${CGreen}%s\n" " $line6 $dest6 <=> $src6" " Out: $out6 | In: $in6" fi if [ "$line7" == "7" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line7 $dest7 <=> $src7" " Out: $out7 | In: $in7" + printf "${CWhite}%-92s${CGreen}%s\n" " $line7 $dest7 <=> $src7" " Out: $out7 | In: $in7" fi if [ "$line8" == "8" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line8 $dest8 <=> $src8" " Out: $out8 | In: $in8" + printf "${CWhite}%-92s${CGreen}%s\n" " $line8 $dest8 <=> $src8" " Out: $out8 | In: $in8" fi if [ "$line9" == "9" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" " $line9 $dest9 <=> $src9" " Out: $out9 | In: $in9" + printf "${CWhite}%-92s${CGreen}%s\n" " $line9 $dest9 <=> $src9" " Out: $out9 | In: $in9" fi if [ "$line10" == "10" ]; then - printf "${CWhite}%-82s${CGreen}%s\n" "$line10 $dest10 <=> $src10" " Out: $out10 | In: $in10" + printf "${CWhite}%-92s${CGreen}%s\n" "$line10 $dest10 <=> $src10" " Out: $out10 | In: $in10" fi echo "" @@ -4661,9 +4665,6 @@ if [ "$NCView" = "WG" ] } # ------------------------------------------------------------------------------------------------------------------------- -##------------------------------------------## -## Modified by ExtremeFiretop [2025-Dec-03] ## -##------------------------------------------## # This function displays the stats UI for page 7 DisplayPage7() { @@ -4672,904 +4673,1059 @@ DisplayPage7() echo -e "$UpdateNotify${CClear}" fi showheader - # Create a temp arp table of connected wifi/lan clients - cat /proc/net/arp > /jffs/addons/rtrmon.d/temparp.txt - # Force create the processed clients list file - touch /jffs/addons/rtrmon.d/processed_clients.txt - # Force create the processed clients list file for VLAN - touch /jffs/addons/rtrmon.d/processed_vlanclients.txt + echo "" + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} Attached Wireless + Wired Clients (Dedicated to @ExtremeFiretop and @visortgw) ${CClear}" + if [ "$SortbyOpt" = "Name" ]; then + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} Sort By: ${InvDkGray}${CGreen} (!)${CWhite}Name ${CClear}${CWhite} | ${CGreen}(@)${CWhite}IP | ${CGreen}(#)${CWhite}MAC${CClear} ${CWhite}| ${CClear}[${CGreen}a${CClear}=Enable/Disable Screen Run-off]${CClear}" + elif [ "$SortbyOpt" = "IP" ]; then + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} Sort By: ${CGreen} (!)${CWhite}Name | ${InvDkGray} ${CGreen}(@)${CWhite}IP ${CClear}${CWhite} | ${CGreen}(#)${CWhite}MAC${CClear} ${CWhite}| ${CClear}[${CGreen}a${CClear}=Enable/Disable Screen Run-off]${CClear}" + elif [ "$SortbyOpt" = "MAC" ]; then + echo -e "${InvGreen} ${CClear}" + echo -e "${InvGreen} ${CClear}${CWhite} Sort By: ${CGreen} (!)${CWhite}Name | ${CGreen}(@)${CWhite}IP | ${InvDkGray} ${CGreen}(#)${CWhite}MAC ${CClear} ${CWhite}| ${CClear}[${CGreen}a${CClear}=Enable/Disable Screen Run-off]${CClear}" + fi + echo -e "${InvGreen} ${CClear}${CDkGray}------------------------------------------------------------------------------------------------------------------------${CClear}" + +################################################################################ +# CONSTANTS AND CONFIGURATION +################################################################################ +NVRAM="nvram" +WL="wl" +ARP="arp" +IFCONFIG="ifconfig" +CAT="cat" + +# Color definitions +#InvGreen="\e[42m" +#InvDkGray="\e[100m" +#CWhite="\e[97m" +#CGreen="\e[92m" +#CDkGray="\e[90m" +#CClear="\e[0m" + +# Temporary files for client tracking and deduplication +PROCESSED_CLIENTS="/tmp/netmon_processed_clients_$$.txt" +PROCESSED_VLAN_CLIENTS="/tmp/netmon_processed_vlan_clients_$$.txt" + +# Sorting Configuration +# Options: "Name", "IP", "MAC" +# Default: "Name" (alphabetical sorting by hostname) +#SortbyOpt="Name" + +# Display width for formatted headers +HEADER_WIDTH=120 + +# Radio configuration variables +IFNAME_24="" +IFNAME_5="" +IFNAME_5_2="" +IFNAME_6="" +IFNAME_6_2="" + +################################################################################ +# ROUTER MODEL DETECTION AND INTERFACE MAPPING +################################################################################ + +# Detect router model and configure interface mappings +detect_router_model() { + local router_model=$(${NVRAM} get productid 2>/dev/null) + [ -z "${router_model}" ] && router_model=$(${NVRAM} get model 2>/dev/null) + + #echo "Detected Router Model: ${router_model}" >&2 + + # Determine radio configuration based on router model + case "${router_model}" in + # Four-band routers: 5GHz, 5GHz, 6GHz, 2.4GHz (wl0=5, wl1=5, wl2=6, wl3=2.4) + GT-AXE16000|GT-BE98) + IFNAME_5=$(${NVRAM} get wl0_ifname 2>/dev/null) + IFNAME_5_2=$(${NVRAM} get wl1_ifname 2>/dev/null) + IFNAME_6=$(${NVRAM} get wl2_ifname 2>/dev/null) + IFNAME_24=$(${NVRAM} get wl3_ifname 2>/dev/null) + ;; - # Per @Stephen Harrington's sugguestion, check NVRAM to see if Wifi is turned on, else mark them as disabled - if [ "$FourBandCustom55624" == "True" ]; then - if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then - MaxSpeed5GhzNow=0 - else - MaxSpeed5GhzNow=$MaxSpeed5Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then - MaxSpeed52GhzNow=0 - else - MaxSpeed52GhzNow=$MaxSpeed5Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then - MaxSpeed6GhzNow=0 - else - MaxSpeed6GhzNow=$MaxSpeed6Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl3_radio) -eq 0 ]; then - MaxSpeed24GhzNow=0 - else - MaxSpeed24GhzNow=$MaxSpeed24Ghz - fi - elif [ "$FourBandCustom56624" == "True" ]; then - if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then - MaxSpeed5GhzNow=0 - else - MaxSpeed5GhzNow=$MaxSpeed5Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then - MaxSpeed6GhzNow=0 - else - MaxSpeed6GhzNow=$MaxSpeed6Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then - MaxSpeed62GhzNow=0 - else - MaxSpeed62GhzNow=$MaxSpeed6Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl3_radio) -eq 0 ]; then - MaxSpeed24GhzNow=0 - else - MaxSpeed24GhzNow=$MaxSpeed24Ghz - fi - elif [ "$ThreeBand2456" == "True" ]; then - if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then - MaxSpeed24GhzNow=0 - else - MaxSpeed24GhzNow=$MaxSpeed24Ghz - fi - if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then - MaxSpeed5GhzNow=0 - else - MaxSpeed5GhzNow=$MaxSpeed5Ghz + # Four-band routers: 5GHz, 6GHz, 6GHz, 2.4GHz (wl0=5, wl1=6, wl2=6, wl3=2.4) + GT-BE98_PRO) + IFNAME_5=$(${NVRAM} get wl0_ifname 2>/dev/null) + IFNAME_6=$(${NVRAM} get wl1_ifname 2>/dev/null) + IFNAME_6_2=$(${NVRAM} get wl2_ifname 2>/dev/null) + IFNAME_24=$(${NVRAM} get wl3_ifname 2>/dev/null) + ;; + + # Three-band routers: 2.4GHz, 5GHz, 6GHz (wl0=2.4, wl1=5, wl2=6) + GT-AXE11000|ZenWiFi_ET8|RT-BE96U|RT-BE92U) + IFNAME_24=$(${NVRAM} get wl0_ifname 2>/dev/null) + IFNAME_5=$(${NVRAM} get wl1_ifname 2>/dev/null) + IFNAME_6=$(${NVRAM} get wl2_ifname 2>/dev/null) + ;; + + # Three-band routers: 2.4GHz, 5GHz, 5GHz (wl0=2.4, wl1=5, wl2=5) + GT-AX11000_PRO|GT-AX11000|ZenWiFi_Pro_XT12|ZenWiFi_XT8) + IFNAME_24=$(${NVRAM} get wl0_ifname 2>/dev/null) + IFNAME_5=$(${NVRAM} get wl1_ifname 2>/dev/null) + IFNAME_5_2=$(${NVRAM} get wl2_ifname 2>/dev/null) + ;; + + # Default two-band routers: 2.4GHz, 5GHz (wl0=2.4, wl1=5) + *) + IFNAME_24=$(${NVRAM} get wl0_ifname 2>/dev/null) + IFNAME_5=$(${NVRAM} get wl1_ifname 2>/dev/null) + ;; + esac + + # Log detected interfaces + #echo "Interface Mapping:" >&2 + #[ -n "${IFNAME_24}" ] && echo " 2.4GHz: ${IFNAME_24}" >&2 + #[ -n "${IFNAME_5}" ] && echo " 5.0GHz: ${IFNAME_5}" >&2 + #[ -n "${IFNAME_5_2}" ] && echo " 5.0GHz-2: ${IFNAME_5_2}" >&2 + #[ -n "${IFNAME_6}" ] && echo " 6.0GHz: ${IFNAME_6}" >&2 + #[ -n "${IFNAME_6_2}" ] && echo " 6.0GHz-2: ${IFNAME_6_2}" >&2 +} + +################################################################################ +# MLO/MLD AWARENESS FUNCTIONS +################################################################################ + +# Read all DHCP lease files including merged leases for MLO/MLD support +read_all_dhcp_leases() { + # Include the merged lease file if it exists (for MLO/MLD clients) + local lease_files="/var/lib/misc/dnsmasq-*.leases /var/lib/misc/dnsmasq.leases" + if [ -f "/tmp/dnsmasq-merged.leases" ]; then + lease_files="${lease_files} /tmp/dnsmasq-merged.leases" + fi + local all_leases="" + all_leases=$(${CAT} ${lease_files} 2>/dev/null) + echo "${all_leases}" +} + +# Unified MLD MAC retrieval logic: given the current dhcpleases and association MAC (in lowercase), +# determine the lookup MAC (which may be the MLD MAC if present). +# For WiFi 7 / MLO clients the MAC used by 'wl assoclist' may NOT be the same MAC +# that appears in ARP/DHCP. This function finds the correct MAC to use for lookups. +get_lookup_mac() { + local maclower="$1" + local leases="$2" + local lookup_mac="${maclower}" + local mld_line="" + local field_count="" + local mld_mac="" + + mld_line=$(echo "${leases}" | grep -i "${maclower}" | head -n1) + if [ -n "${mld_line}" ]; then + field_count=$(echo "${mld_line}" | awk '{print NF; exit}') + if [ "${field_count}" -ge 5 ]; then + mld_mac=$(echo "${mld_line}" | awk '{print $5; exit}') + if [ -n "${mld_mac}" ] && [ "${mld_mac}" != "*" ]; then + lookup_mac=$(echo "${mld_mac}" | awk '{print tolower($0)}') + fi + fi fi - if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then - MaxSpeed6GhzNow=0 - else - MaxSpeed6GhzNow=$MaxSpeed6Ghz + echo "${lookup_mac}" +} + +################################################################################ +# UTILITY FUNCTIONS +################################################################################ + +# Get the bridge name that an interface is enslaved to +get_bridge_for_interface() { + local iface="$1" + local bridge_name="" + + for br in $(ls /sys/class/net 2>/dev/null | grep '^br'); do + if [ -d "/sys/class/net/${br}/brif/${iface}" ]; then + bridge_name="${br}" + break + fi + done + + echo "${bridge_name}" +} + +# Get list of VLAN/AiMesh bridge interfaces from apg_ifnames +get_vlan_bridges() { + local apg_ifnames=$(${NVRAM} get apg_ifnames 2>/dev/null) + if [ -n "${apg_ifnames}" ]; then + echo "${apg_ifnames}" fi - elif [ "$ThreeBand2455" == "True" ]; then - if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then - MaxSpeed24GhzNow=0 +} + +# Check if IP is a local/private address +is_local_ip() { + local ip="$1" + + # Check for private IP ranges + case "${ip}" in + 10.*) return 0 ;; + 192.168.*) return 0 ;; + 172.1[6-9].*) return 0 ;; + 172.2[0-9].*) return 0 ;; + 172.3[0-1].*) return 0 ;; + 169.254.*) return 0 ;; + 127.*) return 0 ;; + *) return 1 ;; + esac +} + +# Get all active wireless interfaces including VIFs (guest networks) +get_wireless_interfaces() { + local temp_file="/tmp/wireless_ifaces_$$.tmp" + + # Get main wireless interfaces + ${IFCONFIG} | grep '^eth[0-9]\|^wl[0-9]' | awk '{print $1}' | while read iface; do + if ${WL} -i "${iface}" status >/dev/null 2>&1; then + echo "${iface}" + fi + done > "${temp_file}" + + # Get VIFs (virtual interfaces for guest networks) from nvram + for wl_unit in 0 1 2 3; do + local vifs=$(${NVRAM} get wl${wl_unit}_vifs 2>/dev/null) + if [ -n "${vifs}" ]; then + for vif in ${vifs}; do + # Check if VIF has an SSID configured (indicates it's active) + local vif_ssid=$(${NVRAM} get ${vif}_ssid 2>/dev/null) + if [ -n "${vif_ssid}" ] && [ "${vif_ssid}" != " " ]; then + # Verify the interface exists and is up + if ${IFCONFIG} "${vif}" >/dev/null 2>&1; then + echo "${vif}" + fi + fi + done + fi + done >> "${temp_file}" + + # Sort and deduplicate + sort -u "${temp_file}" + rm -f "${temp_file}" +} + +# Get band name from interface name based on detected configuration +get_band_from_interface() { + local iface="$1" + + if [ "${iface}" = "${IFNAME_24}" ]; then + echo "2.4GHz" + elif [ "${iface}" = "${IFNAME_5}" ]; then + echo "5.0GHz" + elif [ -n "${IFNAME_5_2}" ] && [ "${iface}" = "${IFNAME_5_2}" ]; then + echo "5.0GHz-2" + elif [ -n "${IFNAME_6}" ] && [ "${iface}" = "${IFNAME_6}" ]; then + echo "6.0GHz" + elif [ -n "${IFNAME_6_2}" ] && [ "${iface}" = "${IFNAME_6_2}" ]; then + echo "6.0GHz-2" else - MaxSpeed24GhzNow=$MaxSpeed24Ghz + echo "" fi - if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then - MaxSpeed5GhzNow=0 - else - MaxSpeed5GhzNow=$MaxSpeed5Ghz +} + +# Get SSID for a main wireless interface +get_ssid_for_interface() { + local iface="$1" + local ssid="" + + # Find the wl unit number for this interface + for wl_unit in 0 1 2 3; do + local unit_iface=$(${NVRAM} get wl${wl_unit}_ifname 2>/dev/null) + if [ "${unit_iface}" = "${iface}" ]; then + ssid=$(${NVRAM} get wl${wl_unit}_ssid 2>/dev/null) + break + fi + done + + echo "${ssid}" +} + +# Pagination control function +# Manages output display with optional row limiting +handle_pagination() { + local line_count=0 + local total_lines=0 + + # If pagination is disabled, just output everything + if [ "${PreventScrolling}" -eq 0 ]; then + cat + return fi - if [ $($timeoutcmd$timeoutsec nvram get wl2_radio) -eq 0 ]; then - MaxSpeed52GhzNow=0 - else - MaxSpeed52GhzNow=$MaxSpeed5Ghz + + # Count total lines first + local temp_file="/tmp/netmon_paginate_$$.tmp" + cat > "${temp_file}" + total_lines=$(wc -l < "${temp_file}") + + # If total lines is less than MaxRows, just display everything + if [ ${total_lines} -le ${MaxRows} ]; then + cat "${temp_file}" + rm -f "${temp_file}" + return fi - else - if [ $($timeoutcmd$timeoutsec nvram get wl0_radio) -eq 0 ]; then - MaxSpeed24GhzNow=0 - else - MaxSpeed24GhzNow=$MaxSpeed24Ghz + + # Display with pagination - stop at MaxRows + while IFS= read -r line; do + echo "${line}" + line_count=$((line_count + 1)) + + if [ ${line_count} -ge ${MaxRows} ]; then + local remaining=$((total_lines - line_count)) + if [ ${remaining} -gt 0 ]; then + echo "" + echo -e "${InvGreen} ${CClear} More rows available (${remaining} remaining) [${CGreen}a${CClear}=Enable/Disable Screen Run-off]${CClear}" + rm -f "${temp_file}" + return + fi + fi + done < "${temp_file}" + + rm -f "${temp_file}" +} + +# Get interface type and band information +# Uses bridge membership to accurately determine guest vs local Wi-Fi +get_interface_info() { + local iface="$1" + local band="" + local type="" + local guest_ssid="" + local bridge_name="" + + # Check if this is a guest/VIF interface by looking for it in bridge interfaces + # Find which bridge this interface is enslaved to + for br in $(ls /sys/class/net 2>/dev/null | grep '^br'); do + if [ -d "/sys/class/net/${br}/brif/${iface}" ]; then + bridge_name="${br}" + break + fi + done + + # Determine if it's a VIF (virtual interface) by checking nvram wlX_vifs + local is_vif=0 + for wl_unit in 0 1 2 3; do + local vifs=$(${NVRAM} get wl${wl_unit}_vifs 2>/dev/null) + if [ -n "${vifs}" ]; then + for vif in ${vifs}; do + if [ "${vif}" = "${iface}" ]; then + is_vif=1 + # Get the base interface to determine band + local base_iface=$(${NVRAM} get wl${wl_unit}_ifname 2>/dev/null) + band=$(get_band_from_interface "${base_iface}") + + # Get SSID for this VIF + guest_ssid=$(${NVRAM} get ${iface}_ssid 2>/dev/null) + if [ -z "${guest_ssid}" ] || [ "${guest_ssid}" = " " ]; then + guest_ssid="Guest Network" + fi + break 2 + fi + done + fi + done + + # Determine type based on bridge membership and VIF status + if [ ${is_vif} -eq 1 ]; then + # It's a VIF - check which bridge it's on + if [ -n "${bridge_name}" ] && [ "${bridge_name}" != "br0" ]; then + type="guest" + else + # VIF on br0 is treated as local Wi-Fi + type="main" + fi + echo "${type}|${band}|${guest_ssid}" + return fi - if [ $($timeoutcmd$timeoutsec nvram get wl1_radio) -eq 0 ]; then - MaxSpeed5GhzNow=0 + + # Not a VIF - determine band for main interfaces + band=$(get_band_from_interface "${iface}") + + if [ -n "${band}" ]; then + type="main" + elif [ "${iface}" = "br0" ]; then + type="lan" else - MaxSpeed5GhzNow=$MaxSpeed5Ghz + type="unknown" fi - fi - if [ "$SortbyOpt" = "Name" ]; then - SortbyNum="1" - elif [ "$SortbyOpt" = "IP" ]; then - SortbyNum="2" - elif [ "$SortbyOpt" = "MAC" ]; then - SortbyNum="3" - else - SortbyNum="1" - fi - prevSortByOpt="$SortbyOpt" + echo "${type}|${band}|" +} - #Testing - #MaxSpeed24GhzNow=0 - #w24updown="UP" #testing - echo "" - echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite} Attached Wireless + Wired Clients ${CClear}" - if [ "$SortbyOpt" = "Name" ]; then - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear}${CWhite} Sort By: ${InvDkGray}${CGreen} (!)${CWhite}Name ${CClear}${CWhite} | ${CGreen}(@)${CWhite}IP | ${CGreen}(#)${CWhite}MAC${CClear}" - elif [ "$SortbyOpt" = "IP" ]; then - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear}${CWhite} Sort By: ${CGreen} (!)${CWhite}Name | ${InvDkGray} ${CGreen}(@)${CWhite}IP ${CClear}${CWhite} | ${CGreen}(#)${CWhite}MAC${CClear}" - elif [ "$SortbyOpt" = "MAC" ]; then - echo -e "${InvGreen} ${CClear}" - echo -e "${InvGreen} ${CClear}${CWhite} Sort By: ${CGreen} (!)${CWhite}Name | ${CGreen}(@)${CWhite}IP | ${InvDkGray} ${CGreen}(#)${CWhite}MAC ${CClear}" - fi - echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------${CClear}" - echo "" +# Convert seconds to hours:minutes format +format_uptime() { + local seconds="$1" + local hours=$((seconds / 3600)) + local minutes=$(((seconds % 3600) / 60)) + printf "%02dh:%02dm" "${hours}" "${minutes}" +} - # --- Local 2.4 GHz: only show heading if clients exist on the base iface --- - if [ "$MaxSpeed24GhzNow" != "0" ]; then - section_output="$(attachedwificlients "$ifname24")" - if [ -n "$section_output" ] && \ - ! echo "$section_output" | grep -q "No Devices Connected"; then - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 2.4GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname24 ${CClear}" - printf '%s\n' "$section_output" - echo "" +# Convert bytes to GB +bytes_to_gb() { + local bytes="$1" + if [ "${bytes}" -eq 0 ] 2>/dev/null; then + echo "0.00" + else + echo "${bytes}" | awk '{printf "%.2f", $1/1024/1024/1024}' fi - else - echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 2.4GHz ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" - echo "" - fi +} - # --- Local 5.0 GHz: only show if clients on base iface --- - #Testing - #MaxSpeed5GhzNow=0 #testing - #w5updown="UP" #testing - if [ "$MaxSpeed5GhzNow" != "0" ]; then - section_output="$(attachedwificlients "$ifname5")" - if [ -n "$section_output" ] && \ - ! echo "$section_output" | grep -q "No Devices Connected"; then - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname5 ${CClear}" - printf '%s\n' "$section_output" - echo "" +# Get IP address for a MAC from ARP table with MLO/MLD awareness +# Prefers IPs with REACHABLE or DELAY neighbor state for more reliable mapping +get_ip_from_mac() { + local mac="$1" + local dhcp_leases="$2" + local ip="" + local mac_normalized="" + mac_normalized=$(echo "${mac}" | tr 'A-F' 'a-f') + + # Get the lookup MAC (may be MLD MAC for WiFi 7 clients) + local lookup_mac=$(get_lookup_mac "${mac_normalized}" "${dhcp_leases}") + + # Try to find all IPs for this MAC in ARP table + local ips="" + if [ -f /proc/net/arp ]; then + ips=$(awk -v mac="${mac_normalized}" 'BEGIN{IGNORECASE=1} tolower($4)==mac {print $1}' /proc/net/arp 2>/dev/null) + fi + + # If we have multiple IPs, prefer one that is REACHABLE or DELAY + if [ -n "${ips}" ]; then + for candidate_ip in ${ips}; do + local arp_status=$(ip neigh show | grep -w "${candidate_ip}" | awk '{print $NF}' 2>/dev/null) + if [ -n "${arp_status}" ] && { [ "${arp_status}" = "REACHABLE" ] || [ "${arp_status}" = "DELAY" ]; }; then + ip="${candidate_ip}" + break + fi + done + # If no REACHABLE/DELAY found, use the last IP as fallback + [ -z "${ip}" ] && ip=$(echo "${ips}" | tail -n 1) fi - else - echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" - echo "" - fi - # --- Local 5.0 GHz (2): only show if clients on base iface --- - #Testing - #FourBandCustom55624="True" #testing - #MaxSpeed52GhzNow=0 #testing - #w52updown="UP" #testing - if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then - if [ "$MaxSpeed52GhzNow" != "0" ]; then - section_output="$(attachedwificlients "$ifname52")" - if [ -n "$section_output" ] && \ - ! echo "$section_output" | grep -q "No Devices Connected"; then - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz (2) ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname52 ${CClear}" - printf '%s\n' "$section_output" - echo "" - fi - else - echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 5.0GHz (2) ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" - echo "" + # Try DHCP leases using lookup_mac if no IP found + if [ -z "${ip}" ]; then + if [ -f /var/lib/misc/dnsmasq.leases ]; then + ip=$(awk -v mac="${lookup_mac}" '{if (tolower($2) == mac) {print $3; exit}}' /var/lib/misc/dnsmasq.leases 2>/dev/null) + fi fi - fi - # --- Local 6.0 GHz: only show if clients on base iface --- - #Testing - #ThreeBand2456="True" #testing - #MaxSpeed6GhzNow=1 #testing - #w6updown="UP" #testing - if [ "$FourBandCustom55624" == "True" ] || \ - [ "$ThreeBand2456" == "True" ] || \ - [ "$FourBandCustom56624" == "True" ]; then - if [ "$MaxSpeed6GhzNow" != "0" ]; then - section_output="$(attachedwificlients "$ifname6")" - if [ -n "$section_output" ] && \ - ! echo "$section_output" | grep -q "No Devices Connected"; then - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname6 ${CClear}" - printf '%s\n' "$section_output" - echo "" - fi - else - echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" - echo "" + # Fallback to arp command + if [ -z "${ip}" ]; then + ip=$(${ARP} -n 2>/dev/null | grep -i "${mac}" | awk '{print $1}' | head -n1) fi - fi - # --- Local 6.0 GHz (2): only show if clients on base iface --- - #Testing - #FourBandCustom56624="True" #testing - #MaxSpeed62GhzNow=0 #testing - #w62updown="UP" #testing - if [ "$FourBandCustom56624" == "True" ]; then - if [ "$MaxSpeed62GhzNow" != "0" ]; then - section_output="$(attachedwificlients "$ifname62")" - if [ -n "$section_output" ] && \ - ! echo "$section_output" | grep -q "No Devices Connected"; then - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz (2) ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $ifname62 ${CClear}" - printf '%s\n' "$section_output" - echo "" - fi + if [ -z "${ip}" ] || [ "${ip}" = "?" ]; then + echo "Unknown" else - echo -e "${InvRed} ${CClear}${InvDkGray} ${CWhite}Local 6.0GHz (2) ${CDkGray}[ ${CRed} Disabled ${CDkGray}]${CClear}" - echo "" + echo "${ip}" fi - fi +} - # Guest Network Clients - Thanks to @ColinTaylor for this methodology of stepping through legit guest network interfaces - cp -f /jffs/addons/rtrmon.d/temparp.txt /jffs/addons/rtrmon.d/temparpvlan.txt +# Get hostname from dnsmasq leases and nvram - MAC-specific with MLO/MLD support +get_hostname() { + local mac="$1" + local ip="$2" + local dhcp_leases="$3" + local hostname="" + local mac_normalized="" + mac_normalized=$(echo "${mac}" | tr 'A-F' 'a-f') - for guestiface in $(nvram get wl0_vifs) $(nvram get wl1_vifs) \ - $(nvram get wl2_vifs) $(nvram get wl3_vifs) - do - guestssid=$(nvram get ${guestiface}_ssid 2>/dev/null) - # Skip VIFs with no SSID at all - [ -z "$guestssid" ] && continue - - bridge_name="" - # Find which bridge this VIF is enslaved to by checking /sys/class/net/br*/brif - for br in $(ls /sys/class/net 2>/dev/null | grep '^br'); do - if [ -d "/sys/class/net/$br/brif/$guestiface" ]; then - bridge_name="$br" - break - fi - done + # Get the lookup MAC (may be MLD MAC for WiFi 7 clients) + local lookup_mac=$(get_lookup_mac "${mac_normalized}" "${dhcp_leases}") - if [ -n "$bridge_name" ] && [ "$bridge_name" != "br0" ]; then - guestlabel="Guest Wi-Fi" - else - guestlabel="Local Wi-Fi" - fi + # Try custom_clientlist first + local custom_clients=$(${NVRAM} get custom_clientlist 2>/dev/null) + if [ -n "${custom_clients}" ]; then + local mac_upper=$(echo "${mac}" | tr 'a-f' 'A-F') + hostname=$(echo "${custom_clients}" | grep -o "<[^>]*>${mac_upper}" | sed 's/^<\([^>]*\)>.*/\1/' | head -n1) + fi - echo -en "${InvGreen} ${CClear}${InvDkGray} ${CWhite}${guestlabel}: ${CGreen}" - printf "%-32s" ${guestssid} - echo -e "${CWhite} ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: $guestiface ${CClear}" + # Try dnsmasq leases using lookup_mac + if [ -z "${hostname}" ] || [ "${hostname}" = " " ]; then + hostname=$(echo "${dhcp_leases}" | grep -i "${lookup_mac}" | awk '{print $4}' | head -n1) + fi - attachedguestclients "$guestiface" - echo "" - done + # Try static DHCP reservations + if [ -z "${hostname}" ] || [ "${hostname}" = " " ] || [ "${hostname}" = "*" ]; then + local dhcp_staticlist=$(${NVRAM} get dhcp_staticlist 2>/dev/null) + if [ -n "${dhcp_staticlist}" ]; then + hostname=$(echo "${dhcp_staticlist}" | grep -i "${lookup_mac}" | cut -d'>' -f1 | sed 's/.*/dev/null | grep 'name =' | awk '{print $4}' | sed 's/\.$//') + fi + fi - echo -e "${InvGreen} ${CClear}${InvDkGray} ${CWhite}Local LAN/Non-VLAN AiMesh ${CDkGray}[ ${CWhite}Enabled ${CDkGray}] ${InvDkGray}${CWhite}IFace: br0 ${CClear}" - #Remove non-LAN records - sed -i -e '/eth0/d' /jffs/addons/rtrmon.d/temparp.txt - sed -i -e '/IP address/d' /jffs/addons/rtrmon.d/temparp.txt - sed -i -e '/00:00:00:00:00:00/d' /jffs/addons/rtrmon.d/temparp.txt - sed -i -e '/0x0/d' /jffs/addons/rtrmon.d/temparp.txt - attachedlanclients - rm -f /jffs/addons/rtrmon.d/processed_clients.txt - rm -f /jffs/addons/rtrmon.d/processed_vlanclients.txt - rm -f /jffs/addons/rtrmon.d/temparp.txt - - #Testing - #FourBandCustom55624="False" #testing - #MaxSpeed52GhzNow=0 #testing - #w52updown="UP" #testing - #ThreeBand2456="False" #testing - #MaxSpeed6GhzNow=0 #testing - #w6updown="UP" #testing - #FourBandCustom56624="False" #testing - #MaxSpeed62GhzNow=0 #testing - #w62updown="UP" #testing -} + # Final fallback + if [ -z "${hostname}" ] || [ "${hostname}" = " " ] || [ "${hostname}" = "*" ]; then + hostname="Unknown" + fi -# ------------------------------------------------------------------------------------------------------------------------- -# multiple DHCP lists can exist. Read through all lists and compile into a single list. + echo "${hostname}" +} -read_all_dhcp_leases() { - # Include the merged lease file if it exists - local lease_files="/var/lib/misc/dnsmasq-*.leases /var/lib/misc/dnsmasq.leases" - if [ -f "/tmp/dnsmasq-merged.leases" ]; then - lease_files="$lease_files /tmp/dnsmasq-merged.leases" - fi - local all_leases - all_leases=$(cat $lease_files 2>/dev/null) - echo "$all_leases" +get_wireless_clients() { + local iface="$1" + ${WL} -i "${iface}" assoclist 2>/dev/null | awk '{print $2}' | tr 'A-F' 'a-f' } -# Unified MLD MAC retrieval logic: given the current dhcpleases and association MAC (in lowercase), -# determine the lookup MAC (which may be the MLD MAC if present). -get_lookup_mac() { - local maclower="$1" - local leases="$2" - local lookup_mac="$maclower" - local mld_line field_count mld_mac - mld_line=$(echo "$leases" | grep -i "$maclower" | head -n1) - if [ -n "$mld_line" ]; then - field_count=$(echo "$mld_line" | awk '{print NF; exit}') - if [ "$field_count" -ge 5 ]; then - mld_mac=$(echo "$mld_line" | awk '{print $5; exit}') - if [ -n "$mld_mac" ] && [ "$mld_mac" != "*" ]; then - lookup_mac=$(echo "$mld_mac" | awk '{print tolower($0)}') - fi +get_wireless_client_details() { + local iface="$1" + local mac="$2" + local dhcp_leases="$3" + local mac_normalized="" + local mac_upper="" + local clientip="" + local hostname="" + local uptime="" + local tx_bytes="" + local rx_bytes="" + local tx_rate="" + local rx_rate="" + local rssi="" + local chanspec="" + + mac_normalized=$(echo "${mac}" | tr 'A-F' 'a-f') + mac_upper=$(echo "${mac}" | tr 'a-f' 'A-F') + + # Get the lookup MAC for WiFi 7 / MLO clients + local lookup_mac=$(get_lookup_mac "${mac_normalized}" "${dhcp_leases}") + + # For WiFi 7 / MLO clients the MAC used by wl (assoclist) may NOT be + # the same MAC that appears in ARP/DHCP. Start with the assoc MAC + # as canonical, then override if we find a better ARP match. + local canonical_mac="${mac}" + local canonlower="${mac_normalized}" + local canonupper="${mac_upper}" + + # Get client statistics from wl + local sta_info=$(${WL} -i "${iface}" sta_info "${mac}" 2>/dev/null) + + if [ -n "${sta_info}" ]; then + local network_time=$(echo "${sta_info}" | awk '/in network/ {print $3}') + if [ -n "${network_time}" ]; then + uptime=$(format_uptime "${network_time}") + else + uptime="Unknown" + fi + + tx_bytes=$(echo "${sta_info}" | awk '/tx total bytes:/ {print $4}') + rx_bytes=$(echo "${sta_info}" | awk '/rx data bytes:/ {print $4}') + tx_rate=$(echo "${sta_info}" | awk '/rate of last tx pkt:/ {print $6}') + rx_rate=$(echo "${sta_info}" | awk '/rate of last rx pkt:/ {print $6}') + rssi=$(echo "${sta_info}" | awk '/smoothed rssi:/ {print $3}') + chanspec=$(echo "${sta_info}" | awk '/chanspec/ {print $2}') fi - fi - echo "$lookup_mac" -} -# attachedwificlients pulls connected client info from wl, arp and nvram -attachedwificlients () -{ - iface="$1" - rm -f /jffs/addons/rtrmon.d/wificlients$iface.txt - wl -i $iface assoclist > /jffs/addons/rtrmon.d/wificlients$iface.txt 2>/dev/null - maxclientcount=$(cat /jffs/addons/rtrmon.d/wificlients$iface.txt | wc -l) - rm -f /jffs/addons/rtrmon.d/clientlist$iface.txt - dhcpleases="$(read_all_dhcp_leases)" - local clients - clients="$(nvram get custom_clientlist)" - # Number of '<...>' entries = NF - 1 (first field is empty before first '<') - local maxextractcount - maxextractcount=$(echo "$clients" | awk -F'<' '{print NF}') - - local clientcount=0 - while [ $clientcount -le $maxclientcount ] - do - clientname="" - conntime="" - clientip="" - paddedclientip="" - - clientcount=$((clientcount+1)) - local clientmac=$(awk 'NR=='$clientcount' {print $2}' /jffs/addons/rtrmon.d/wificlients$iface.txt) - - [ -z "$clientmac" ] && continue - - networktime=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/in network/ {print $3}') 2>/dev/null - conntime=$(date -d@$networktime -u +%Hh:%Mm) 2>/dev/null - txtotalbytes=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/tx total bytes:/ {print $4}') 2>/dev/null - rxtotalbytes=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rx data bytes:/ {print $4}') 2>/dev/null - txratekbps=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rate of last tx pkt:/ {print $6}') 2>/dev/null - rxratekbps=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rate of last rx pkt:/ {print $6}') 2>/dev/null - sigstrength=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/smoothed rssi:/ {print $3}') 2>/dev/null - chanspec=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/chanspec/ {print $2}') 2>/dev/null - - maclower=$(echo "$clientmac" | awk '{print tolower($0)}') 2>/dev/null - - # For WiFi 7 / MLO clients the MAC used by wl (assoclist) may NOT be - # the same MAC that appears in ARP/DHCP. Start with the assoc MAC - # as canonical, then override if we find a better ARP match. - canonical_mac="$clientmac" - canonlower="$maclower" - - # --- MLD / dnsmasq lookup helper --- - lookup_mac=$(get_lookup_mac "$maclower" "$dhcpleases") - - # 1) Try to find IPs for this MAC directly in the temp ARP table - ips=$(awk -v mac="$maclower" ' - BEGIN{IGNORECASE=1} - tolower($4)==mac {print $1} - ' /jffs/addons/rtrmon.d/temparp.txt 2>/dev/null) + # Try to find IP for this MAC using MLO/MLD aware lookup + # 1) Try direct match in ARP table - collect all IPs + local ips="" + if [ -f /proc/net/arp ]; then + ips=$(awk -v mac="${mac_normalized}" 'BEGIN{IGNORECASE=1} tolower($4)==mac {print $1}' /proc/net/arp 2>/dev/null) # 2) If that fails, try a fuzzy match using the middle 4 bytes of the MAC - if [ -z "$ips" ]; then - mac_mid4=$(echo "$maclower" | awk -F: '{print $2":"$3":"$4":"$5}') - if [ -n "$mac_mid4" ]; then - arp_line=$(awk -v mid="$mac_mid4" ' - BEGIN{IGNORECASE=1} - index(tolower($4), mid) > 0 {print; exit} - ' /jffs/addons/rtrmon.d/temparp.txt 2>/dev/null) - if [ -n "$arp_line" ]; then - clientip=$(echo "$arp_line" | awk '{print $1}') - canonical_mac=$(echo "$arp_line" | awk '{print $4}') - canonlower=$(echo "$canonical_mac" | awk '{print tolower($0)}') + if [ -z "${ips}" ]; then + local mac_mid4=$(echo "${mac_normalized}" | awk -F: '{print $2":"$3":"$4":"$5}') + if [ -n "${mac_mid4}" ]; then + local arp_line=$(awk -v mid="${mac_mid4}" 'BEGIN{IGNORECASE=1} index(tolower($4), mid) > 0 {print; exit}' /proc/net/arp 2>/dev/null) + if [ -n "${arp_line}" ]; then + clientip=$(echo "${arp_line}" | awk '{print $1}') + canonical_mac=$(echo "${arp_line}" | awk '{print $4}') + canonlower=$(echo "${canonical_mac}" | tr 'A-F' 'a-f') + canonupper=$(echo "${canonical_mac}" | tr 'a-f' 'A-F') fi fi fi - # 3) If we had multiple IPs from a direct match, prefer one that is REACHABLE/DELAY - if [ -z "$clientip" ] && [ -n "$ips" ]; then - for ip in $ips; do - arp_status=$(ip neigh show | grep -w "$ip" | awk '{print $NF}') 2>/dev/null - if [ -z "$arp_status" ] || { [ "$arp_status" != "REACHABLE" ] && [ "$arp_status" != "DELAY" ]; }; then - [ -z "$sigstrength" ] && conntime="STALE" + # 3) If we had multiple IPs from direct match, prefer one that is REACHABLE/DELAY + if [ -z "${clientip}" ] && [ -n "${ips}" ]; then + for ip in ${ips}; do + local arp_status=$(ip neigh show | grep -w "${ip}" | awk '{print $NF}' 2>/dev/null) + if [ -z "${arp_status}" ] || { [ "${arp_status}" != "REACHABLE" ] && [ "${arp_status}" != "DELAY" ]; }; then + # Mark as stale if we have no signal strength + [ -z "${rssi}" ] && uptime="STALE" continue else - clientip="$ip" + clientip="${ip}" break fi done - [ -z "$clientip" ] && clientip=$(echo "$ips" | tail -n 1) + # If no REACHABLE/DELAY found, use the last IP as fallback + [ -z "${clientip}" ] && clientip=$(echo "${ips}" | tail -n 1) fi + fi - # 4) Final fallback: /proc/net/arp using the canonical MAC - if [ -z "$clientip" ]; then - clientip=$(awk -v mac="$canonlower" ' - BEGIN{IGNORECASE=1} - tolower($4)==mac {print $1} - ' /proc/net/arp 2>/dev/null | sort | uniq | tail -n 1) - fi + # 4) Final fallback using canonical MAC + if [ -z "${clientip}" ]; then + clientip=$(awk -v mac="${canonlower}" 'BEGIN{IGNORECASE=1} tolower($4)==mac {print $1}' /proc/net/arp 2>/dev/null | sort | uniq | tail -n 1) + fi - paddedclientip=$(echo "${clientip}" | \ - grep -o -E '([0-9]*\.|[0-9]*)' | \ - awk '{printf( "%03d\n", $1)}' | tr '\n' '.' | sed 's/.$//') 2>/dev/null - - # Traffic/rate conversions - txtotalgb=$(echo $txtotalbytes | awk -v txb=$txtotalbytes 'BEGIN{printf "%0.2f\n", txb/1024/1024/1024}') 2>/dev/null - rxtotalgb=$(echo $rxtotalbytes | awk -v rxb=$rxtotalbytes 'BEGIN{printf "%0.2f\n", rxb/1024/1024/1024}') 2>/dev/null - txratembps=$(echo $txratekbps | awk -v txm=$txratekbps 'BEGIN{printf "%0.1f\n", txm/1000}') 2>/dev/null - rxratembps=$(echo $rxratekbps | awk -v rxm=$rxratekbps 'BEGIN{printf "%0.1f\n", rxm/1000}') 2>/dev/null - - # Try custom_clientlist first (match either assoc MAC or canonical ARP MAC) - local found=0 - local counter=2 - canonupper=$(echo "$canonical_mac" | tr 'a-f' 'A-F') - while [ $counter -le $maxextractcount ] - do - local clientextract - clientextract="$(echo "$clients" | cut -d "<" -f"$counter" | cut -d ">" -f1,2)" - - [ -z "$clientextract" ] && { counter=$((counter+1)); continue; } - - local client - local mac - client="$(echo "$clientextract" | awk -F ">" '{print $1}')" - mac="$(echo "$clientextract" | awk -F ">" '{print $2}')" - - if [ "$mac" = "$clientmac" ] || [ "$mac" = "$canonupper" ]; then - clientname="$client" - found=1 - break - fi + # If still no IP, try DHCP leases with lookup_mac + if [ -z "${clientip}" ]; then + clientip=$(echo "${dhcp_leases}" | grep -i "${lookup_mac}" | awk '{print $3}' | head -n1) + fi - counter=$((counter+1)) - done + # For isolated guest networks, client may not appear in main ARP table + # Still display the client with "Unknown" IP if we have wireless stats + if [ -z "${clientip}" ]; then + if [ -n "${rssi}" ]; then + # Client is actively connected via wireless, just no IP visible + clientip="Unknown" + else + # No IP and no wireless stats - skip this client + return + fi + fi - # Fallback: name from dnsmasq leases using lookup_mac - if [ $found -ne 1 ]; then - clientname=$(echo "$dhcpleases" | grep -i "$lookup_mac" | awk '{print $4}') 2>/dev/null - if [ -z "$clientname" ] || [ "$clientname" = "*" ]; then - clientname="UNKNOWN" - fi + # Check if this canonical MAC has already been processed + # This prevents the same device from appearing in both Wi-Fi and LAN sections + if [ -f "${PROCESSED_CLIENTS}" ]; then + if grep -qi "^${canonupper}$" "${PROCESSED_CLIENTS}" 2>/dev/null; then + return fi + fi - if [ -n "$paddedclientip" ] && [ "$paddedclientip" != "000.000.000.000" ]; then - # Track by canonical MAC so the same device won't show again under LAN - if grep -qi "$canonupper" /jffs/addons/rtrmon.d/processed_clients.txt 2>/dev/null; then - continue + # Track this canonical MAC as processed + echo "${canonupper}" >> "${PROCESSED_CLIENTS}" + + # Get hostname using MLO/MLD aware lookup + hostname=$(get_hostname "${canonical_mac}" "${clientip}" "${dhcp_leases}") + + # Convert traffic values + local tx_gb=$(bytes_to_gb "${tx_bytes:-0}") + local rx_gb=$(bytes_to_gb "${rx_bytes:-0}") + local tx_mbps=$(echo "${tx_rate:-0}" | awk '{printf "%.1f", $1/1000}') + local rx_mbps=$(echo "${rx_rate:-0}" | awk '{printf "%.1f", $1/1000}') + + # Determine detailed band information (NSS and bandwidth) + local bandwidth="" + local bw_mhz="" + local nss="" + + # Try to extract bandwidth from various fields in sta_info + # Method 1: Check for "link bandwidth" line + local link_bw_line=$(echo "${sta_info}" | grep -i 'link bandwidth') + if [ -n "${link_bw_line}" ]; then + bw_mhz=$(echo "${link_bw_line}" | grep -o '[0-9]\{2,3\}' | head -n1) + fi + + # Method 2: Extract from chanspec if bandwidth not found + if [ -z "${bw_mhz}" ] && [ -n "${chanspec}" ]; then + local chanspec_line=$(echo "${sta_info}" | grep 'chanspec') + if [ -n "${chanspec_line}" ]; then + # Extract bandwidth from chanspec (format: "100/160" where 160 is the bandwidth) + if echo "${chanspec_line}" | grep '/' >/dev/null 2>&1; then + bw_mhz=$(echo "${chanspec_line}" | sed 's/.*\/\([0-9]\{2,3\}\).*/\1/') else - echo "$canonupper" >> /jffs/addons/rtrmon.d/processed_clients.txt + bw_mhz=$(echo "${chanspec_line}" | grep -o '[0-9]\{2,3\}' | tail -n1) fi + fi + fi - # Remove this canonical MAC from the temp ARP table - sed -i -e '/'$canonlower'/d' /jffs/addons/rtrmon.d/temparp.txt - - echo "$clientname,$paddedclientip,$canonupper,$conntime,$txtotalgb,$rxtotalgb,$txratembps,$rxratembps,$sigstrength,$chanspec" \ - >> /jffs/addons/rtrmon.d/clientlist$iface.txt + # Method 3: Try OMI line for bandwidth + if [ -z "${bw_mhz}" ]; then + local omi_line=$(echo "${sta_info}" | grep 'OMI') + if [ -n "${omi_line}" ]; then + bw_mhz=$(echo "${omi_line}" | grep -o '[0-9]\{2,3\}[Mm][Hh][Zz]' | grep -o '[0-9]\{2,3\}') fi - done + fi - if [ -f "/jffs/addons/rtrmon.d/clientlist$iface.txt" ]; then - if [ $maxclientcount -ge 1 ]; then - sort -f -d -o /jffs/addons/rtrmon.d/clientlist$iface.txt -k "$SortbyNum" -t , /jffs/addons/rtrmon.d/clientlist$iface.txt 2>/dev/null - column -t -s',' -o' | ' -N Name,IP,MAC,Uptime,"TX GB","RX GB","TX Mbps","RX Mbps","Sig","Band" /jffs/addons/rtrmon.d/clientlist$iface.txt | sed 's/^/ /' - else - echo -e " No Devices Connected" - fi - else - echo -e " No Devices Connected" + # Extract NSS (Number of Spatial Streams) + # Method 1: Check OMI line + local omi_line=$(echo "${sta_info}" | grep 'OMI') + if [ -n "${omi_line}" ]; then + nss=$(echo "${omi_line}" | grep -o 'tx=[0-9]ss' | grep -o '[0-9]' | head -n1) fi -} + # Method 2: Check nrate line if NSS not found + if [ -z "${nss}" ]; then + local nrate_line=$(echo "${sta_info}" | grep 'tx nrate\|rx nrate' | head -n1) + if [ -n "${nrate_line}" ]; then + nss=$(echo "${nrate_line}" | grep -o 'Nss [0-9]' | grep -o '[0-9]') + fi + fi -# ------------------------------------------------------------------------------------------------------------------------- -# attachedguestclients pulls connected client info from wl, arp and nvram -##------------------------------------------## -## Modified by ExtremeFiretop [2025-Dec-03] ## -##------------------------------------------## -# attachedguestclients pulls connected client info from wl, arp and nvram -##------------------------------------------## -## Modified by ExtremeFiretop [2025-Dec-04] ## -##------------------------------------------## -attachedguestclients() { - iface="$1" - rm -f /jffs/addons/rtrmon.d/wificlients$iface.txt - wl -i "$iface" assoclist > /jffs/addons/rtrmon.d/wificlients$iface.txt 2>/dev/null - maxclientcount=$(cat /jffs/addons/rtrmon.d/wificlients$iface.txt | wc -l) - rm -f /jffs/addons/rtrmon.d/clientlist$iface.txt - dhcpleases="$(read_all_dhcp_leases)" - local clients - clients="$(nvram get custom_clientlist)" - local maxextractcount - maxextractcount=$(echo "$clients" | awk -F'<' '{print NF}') - - local clientcount=0 - while [ $clientcount -le $maxclientcount ] - do - clientname="" - conntime="" - clientip="" - paddedclientip="" - clientcount=$((clientcount+1)) - local clientmac=$(awk 'NR=='$clientcount' {print $2}' /jffs/addons/rtrmon.d/wificlients$iface.txt) - - if [ -z "$clientmac" ]; then - continue - fi - - networktime=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/in network/ {print $3}') 2>/dev/null - conntime=$(date -d@$networktime -u +%Hh:%Mm) 2>/dev/null - txtotalbytes=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/tx total bytes:/ {print $4}') 2>/dev/null - rxtotalbytes=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rx data bytes:/ {print $4}') 2>/dev/null - txratekbps=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rate of last tx pkt:/ {print $6}') 2>/dev/null - rxratekbps=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/rate of last rx pkt:/ {print $6}') 2>/dev/null - sigstrength=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/smoothed rssi:/ {print $3}') 2>/dev/null - chanspec=$(wl -i $iface sta_info $clientmac | awk -F ' ' '/chanspec/ {print $2}') 2>/dev/null - maclower=$(echo "$clientmac" | awk '{print tolower($0)}') 2>/dev/null - - # Start with assoc MAC as canonical, may override with ARP MAC (WiFi7 / MLO case). - canonical_mac="$clientmac" - canonlower="$maclower" - - # 1) Try ARP in temparp.txt for canonical MAC. - ips=$(awk -v mac="$canonlower" ' - BEGIN{IGNORECASE=1} - tolower($4)==mac {print $1} - ' /jffs/addons/rtrmon.d/temparp.txt 2>/dev/null) - - # 2) If no direct ARP match, try fuzzy match on middle 4 bytes. - if [ -z "$ips" ]; then - mac_mid4=$(echo "$maclower" | awk -F: '{print $2":"$3":"$4":"$5}') - if [ -n "$mac_mid4" ]; then - arp_line=$(awk -v mid="$mac_mid4" ' - BEGIN{IGNORECASE=1} - index(tolower($4), mid) > 0 {print; exit} - ' /jffs/addons/rtrmon.d/temparp.txt 2>/dev/null) - if [ -n "$arp_line" ]; then - clientip=$(echo "$arp_line" | awk '{print $1}') - canonical_mac=$(echo "$arp_line" | awk '{print $4}') - canonlower=$(echo "$canonical_mac" | awk '{print tolower($0)}') + # Method 3: Check VHT SET if NSS still not found + if [ -z "${nss}" ]; then + local vht_line=$(echo "${sta_info}" | grep 'VHT SET' -A 1 | tail -n1) + if [ -n "${vht_line}" ]; then + nss=$(echo "${vht_line}" | grep -o '[0-9]x[0-9]' | head -n1 | cut -d'x' -f1) fi - fi fi - # 3) If we had a set of ARP IPs from direct match, choose REACHABLE/DELAY if possible. - if [ -z "$clientip" ] && [ -n "$ips" ]; then - for ip in $ips; do - arp_status=$(ip neigh show | grep -w "$ip" | awk '{print $NF}') 2>/dev/null - if [ -z "$arp_status" ] || { [ "$arp_status" != "REACHABLE" ] && [ "$arp_status" != "DELAY" ]; }; then - [ -z "$sigstrength" ] && conntime="STALE" - continue + # Format bandwidth display + if [ -n "${bw_mhz}" ]; then + if [ -n "${nss}" ]; then + bandwidth="${nss}x${nss}:${bw_mhz}" else - clientip="$ip" - break + bandwidth="0x0:${bw_mhz}" fi - done - [ -z "$clientip" ] && clientip=$(echo "$ips" | tail -n 1) - fi - - # 4) Final ARP fallback: /proc/net/arp with canonical MAC. - if [ -z "$clientip" ]; then - clientip=$(awk -v mac="$canonlower" ' - BEGIN{IGNORECASE=1} - tolower($4)==mac {print $1} - ' /proc/net/arp 2>/dev/null | sort | uniq | tail -n 1) - fi - - # 5) NEW: If ARP could not give us an IP (guest VLAN case), - # fall back to dnsmasq leases for this canonical MAC. - if [ -z "$clientip" ]; then - lease_line=$(echo "$dhcpleases" | awk -v mac="$canonlower" ' - BEGIN{IGNORECASE=1} - tolower($2)==mac {print; exit} - ') - if [ -n "$lease_line" ]; then - clientip=$(echo "$lease_line" | awk '{print $3}') - fi + else + # Fallback to basic band from interface or chanspec + if [ -n "${chanspec}" ]; then + case "${chanspec}" in + *6g*) bandwidth="6G" ;; + *5g*) bandwidth="5G" ;; + *2g*) bandwidth="2.4G" ;; + *) bandwidth=$(get_band_from_interface "${iface}" | sed 's/GHz//; s/\.0//; s/-2$/2/') ;; + esac + else + bandwidth=$(get_band_from_interface "${iface}" | sed 's/GHz//; s/\.0//; s/-2$/2/') + fi + + # If still no bandwidth info, mark as unknown + [ -z "${bandwidth}" ] && bandwidth="?" fi - paddedclientip=$(echo "${clientip}" | \ - grep -o -E '([0-9]*\.|[0-9]*)' | \ - awk '{printf( "%03d\n", $1)}' | tr '\n' '.' | sed 's/.$//') 2>/dev/null + # Output in pipe-delimited format for sorting: name|ip|mac|other_fields + printf "%s|%s|%s|%s|%s|%s|%s|%s|%s|%s\n" \ + "${hostname:0:16}" "${clientip}" "${canonupper}" "${uptime}" \ + "${tx_gb}" "${rx_gb}" "${tx_mbps}" "${rx_mbps}" "${rssi:--}" "${bandwidth}" +} - # Conversions - txtotalgb=$(echo $txtotalbytes | awk '{printf "%0.2f", $1/1024/1024/1024}') 2>/dev/null - rxtotalgb=$(echo $rxtotalbytes | awk '{printf "%0.2f", $1/1024/1024/1024}') 2>/dev/null - txratembps=$(echo $txratekbps | awk '{printf "%0.1f", $1/1000}') 2>/dev/null - rxratembps=$(echo $rxratekbps | awk '{printf "%0.1f", $1/1000}') 2>/dev/null +# Sort and format wireless client output +sort_wireless_clients() { + local temp_file="$1" + local sort_field="$2" + + if [ ! -s "${temp_file}" ]; then + return + fi + + # Sort by the specified field (1=Name, 2=IP, 3=MAC) + sort -t'|' -k${sort_field},${sort_field} "${temp_file}" | while IFS='|' read name ip mac uptime tx_gb rx_gb tx_mbps rx_mbps rssi bandwidth; do + printf " %-16s | %-15s | %-17s | %-8s | %5s | %5s | %7s | %7s | %3s | %s\n" \ + "${name}" "${ip}" "${mac}" "${uptime}" "${tx_gb}" "${rx_gb}" "${tx_mbps}" "${rx_mbps}" "${rssi}" "${bandwidth}" + done +} - # Resolve client name from custom_clientlist (assoc MAC OR canonical ARP MAC). - local found=0 - local counter=2 - canonupper=$(echo "$canonical_mac" | tr 'a-f' 'A-F') - while [ $counter -le $maxextractcount ] - do - local clientextract - clientextract="$(echo "$clients" | cut -d "<" -f"$counter" | cut -d ">" -f1,2)" +get_lan_clients() { + local dhcp_leases="$1" + local sort_field="$2" + local temp_file="/tmp/lan_clients_$$.tmp" + local temp_output="/tmp/lan_output_$$.tmp" - [ -z "$clientextract" ] && { counter=$((counter+1)); continue; } + if [ -f /proc/net/arp ]; then + ${CAT} /proc/net/arp | awk 'NR>1 && $3!="0x0" && $4!="00:00:00:00:00:00" {print $1, $4}' > "${temp_file}" + else + ${ARP} -n 2>/dev/null | awk 'NR>1 && $1!="?" {print $1, $3}' > "${temp_file}" + fi - local client - local mac - client="$(echo "$clientextract" | awk -F ">" '{print $1}')" - mac="$(echo "$clientextract" | awk -F ">" '{print $2}')" + # Group IPs by MAC to handle multiple IPs per MAC + local processed_macs_local="" + > "${temp_output}" - if [ "$mac" = "$clientmac" ] || [ "$mac" = "$canonupper" ]; then - clientname="$client" - found=1 - break - fi + while read ip mac; do + [ -z "${mac}" ] || [ -z "${ip}" ] && continue + [ "${ip}" = "IP" ] && continue - counter=$((counter+1)) - done + if ! is_local_ip "${ip}"; then + continue + fi - # Fallback: name from dnsmasq leases for canonical MAC. - if [ $found -ne 1 ]; then - lookup_mac="$canonlower" - clientname=$(echo "$dhcpleases" | awk -v mac="$lookup_mac" ' - BEGIN{IGNORECASE=1} - tolower($2)==mac {print $4; exit} - ') 2>/dev/null - if [ -z "$clientname" ] || [ "$clientname" = "*" ]; then - clientname="UNKNOWN" - fi - fi + local mac_normalized=$(echo "${mac}" | tr 'A-F' 'a-f') + local mac_upper=$(echo "${mac}" | tr 'a-f' 'A-F') - if [ -n "$paddedclientip" ] && [ "$paddedclientip" != "000.000.000.000" ]; then - # Mark canonical MAC as processed so it won't also show under LAN. - if grep -qi "$canonupper" /jffs/addons/rtrmon.d/processed_clients.txt 2>/dev/null; then - continue - else - echo "$canonupper" >> /jffs/addons/rtrmon.d/processed_clients.txt - fi + # Skip if already processed this MAC in this function + echo "${processed_macs_local}" | grep -q "${mac_normalized}" && continue - # Prefer to remove from temparp.txt by IP (handles cases where ARP MAC != client MAC). - if [ -n "$clientip" ]; then - sed -i -e "/^$clientip[[:space:]]/d" /jffs/addons/rtrmon.d/temparp.txt - else - sed -i -e '/'$canonlower'/d' /jffs/addons/rtrmon.d/temparp.txt - fi + # Skip if this MAC was already shown in wireless section + if [ -f "${PROCESSED_CLIENTS}" ]; then + if grep -qi "^${mac_upper}$" "${PROCESSED_CLIENTS}" 2>/dev/null; then + continue + fi + fi + + # Track this MAC as processed + echo "${mac_upper}" >> "${PROCESSED_CLIENTS}" - echo "$clientname,$paddedclientip,$canonupper,$conntime,$txtotalgb,$rxtotalgb,$txratembps,$rxratembps,$sigstrength,$chanspec" \ - >> /jffs/addons/rtrmon.d/clientlist$iface.txt + # Find all IPs for this MAC and prefer REACHABLE/DELAY + local all_ips=$(grep -i "${mac}" "${temp_file}" | awk '{print $1}') + local best_ip="" + + if [ -n "${all_ips}" ]; then + for candidate_ip in ${all_ips}; do + local arp_status=$(ip neigh show | grep -w "${candidate_ip}" | awk '{print $NF}' 2>/dev/null) + if [ -n "${arp_status}" ] && { [ "${arp_status}" = "REACHABLE" ] || [ "${arp_status}" = "DELAY" ]; }; then + best_ip="${candidate_ip}" + break + fi + done + # Fallback to first IP if no REACHABLE/DELAY found + [ -z "${best_ip}" ] && best_ip=$(echo "${all_ips}" | head -n1) + else + best_ip="${ip}" + fi + + local hostname=$(get_hostname "${mac}" "${best_ip}" "${dhcp_leases}") + # Output in pipe-delimited format: name|ip|mac + printf "%s|%s|%s\n" "${hostname:0:16}" "${best_ip}" "${mac}" >> "${temp_output}" + processed_macs_local="${processed_macs_local} ${mac_normalized}" + done < "${temp_file}" + + rm -f "${temp_file}" + + # Sort and format output + if [ -s "${temp_output}" ]; then + sort -t'|' -k${sort_field},${sort_field} "${temp_output}" | while IFS='|' read name ip mac; do + printf " %-16s | %-15s | %s\n" "${name}" "${ip}" "${mac}" + done fi - done + + rm -f "${temp_output}" +} - if [ -f "/jffs/addons/rtrmon.d/clientlist$iface.txt" ]; then - if [ $maxclientcount -ge 1 ]; then - sort -f -d -o /jffs/addons/rtrmon.d/clientlist$iface.txt -k "$SortbyNum" -t , /jffs/addons/rtrmon.d/clientlist$iface.txt 2>/dev/null - column -t -s',' -o' | ' -N Name,IP,MAC,Uptime,"TX GB","RX GB","TX Mbps","RX Mbps","Sig","Band" /jffs/addons/rtrmon.d/clientlist$iface.txt | sed 's/^/ /' - else - echo -e " No Devices Connected" +get_primary_subnet() { + local br0_ip=$(${IFCONFIG} br0 2>/dev/null | grep 'inet addr:' | awk '{print $2}' | cut -d':' -f2) + if [ -z "${br0_ip}" ]; then + br0_ip=$(${IFCONFIG} br0 2>/dev/null | awk '/inet / {print $2}') + fi + + if [ -n "${br0_ip}" ]; then + echo "${br0_ip}" | awk -F'.' '{print $1"."$2"."$3".0/24"}' fi - else - echo -e " No Devices Connected" - fi } +# Get subnet for a specific bridge interface +get_bridge_subnet() { + local bridge="$1" + local bridge_ip=$(${IFCONFIG} "${bridge}" 2>/dev/null | grep 'inet addr:' | awk '{print $2}' | cut -d':' -f2) + if [ -z "${bridge_ip}" ]; then + bridge_ip=$(${IFCONFIG} "${bridge}" 2>/dev/null | awk '/inet / {print $2}') + fi -# ------------------------------------------------------------------------------------------------------------------------- -# attachedvlanclients pulls connected client info from wl, arp and nvram - -# attachedvlanclients pulls connected client info from wl, arp and nvram -attachedvlanclients() { - iface="$1" - vlansfound=1 - maxclientcount=$(cat /jffs/addons/rtrmon.d/temparpvlan.txt | wc -l) - maxclientcount=$((maxclientcount-1)) #To account for header row - rm -f /jffs/addons/rtrmon.d/vlanclients$iface.txt - dhcpleases="$(read_all_dhcp_leases)" - local clients - clients="$(nvram get custom_clientlist)" - local maxextractcount - maxextractcount=$(echo "$clients" | awk -F'<' '{print NF}') - - local clientcount=1 #Increased to 1 from 0, to account for header row - while [ $clientcount -le $maxclientcount ] - do - clientname="" - conntime="" - clientip="" - paddedclientip="" - interface_name="" - clientcount=$((clientcount+1)) #This would make it start on row 2, skipping header row - local clientmac=$(awk 'NR=='$clientcount' {print $4}' /jffs/addons/rtrmon.d/temparpvlan.txt | xargs) - - if [ -z "$clientmac" ]; then - continue - fi - - macupper=$(echo "$clientmac" | tr 'a-f' 'A-F') - macprefix=$(echo "$macupper" | awk -F ':' '{print $1":"$2":"$3":"$4":"$5}') 2>/dev/null - clientbridgeid=$(awk 'NR=='$clientcount' {print $6}' /jffs/addons/rtrmon.d/temparpvlan.txt | xargs) - if [ -z "$clientbridgeid" ] || [ "$clientbridgeid" != "$iface" ]; then - continue - else - vlansfound=0 + if [ -n "${bridge_ip}" ]; then + echo "${bridge_ip}" | awk -F'.' '{print $1"."$2"."$3".0/24"}' fi +} - interfaces=$(ip link show | grep -E 'wl|wlan' | awk -F: '{print $2}' | tr -d ' ') - for wirelessface in $interfaces; do - if wl -i "$wirelessface" assoclist 2>/dev/null | grep -iq "$macprefix"; then - interface_name="$wirelessface" - continue - fi - done +get_bridge_clients() { + local bridge="$1" + local dhcp_leases="$2" + local sort_field="$3" + local temp_file="/tmp/bridge_clients_$$.tmp" + local temp_output="/tmp/bridge_output_$$.tmp" - networktime=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/in network/ {print $3}') 2>/dev/null - if [ -z "$networktime" ]; then - conntime="AiMesh" + # Get clients from ARP table that are on this specific bridge (Device column) + if [ -f /proc/net/arp ]; then + ${CAT} /proc/net/arp | awk -v bridge="${bridge}" 'NR>1 && $3!="0x0" && $4!="00:00:00:00:00:00" && $6==bridge {print $1, $4, $6}' > "${temp_file}" else - conntime=$(date -d@$networktime -u +%Hh:%Mm) 2>/dev/null + # Fallback: if arp command is used, we won't have bridge info + rm -f "${temp_file}" + return fi - txtotalbytes=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/tx total bytes:/ {print $4}') 2>/dev/null - rxtotalbytes=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/rx data bytes:/ {print $4}') 2>/dev/null - txratekbps=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/rate of last tx pkt:/ {print $6}') 2>/dev/null - rxratekbps=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/rate of last rx pkt:/ {print $6}') 2>/dev/null - sigstrength=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/smoothed rssi:/ {print $3}') 2>/dev/null - chanspec=$(wl -i $interface_name sta_info $clientmac | awk -F ' ' '/chanspec/ {print $2}') 2>/dev/null - maclower=$(echo "$clientmac" | awk '{print tolower($0)}') 2>/dev/null - lookup_mac=$(get_lookup_mac "$maclower" "$dhcpleases") + # Group IPs by MAC to handle multiple IPs per MAC + local processed_macs_local="" + > "${temp_output}" + + while read ip mac device; do + [ -z "${mac}" ] || [ -z "${ip}" ] && continue - ips=$(grep "$clientmac" "/jffs/addons/rtrmon.d/temparp.txt" | awk '{print $1}') 2>/dev/null + local mac_normalized=$(echo "${mac}" | tr 'A-F' 'a-f') + local mac_upper=$(echo "${mac}" | tr 'a-f' 'A-F') - for ip in $ips; do - arp_status=$(ip neigh show | grep -w "$ip" | awk '{print $NF}') 2>/dev/null - if [ -z "$arp_status" ] || { [ "$arp_status" != "REACHABLE" ] && [ "$arp_status" != "DELAY" ]; }; then - if [ -z "$sigstrength" ]; then - conntime="STALE" + # Skip if already processed this MAC in this function + echo "${processed_macs_local}" | grep -q "${mac_normalized}" && continue + + # Skip if this MAC was already shown in wireless section + if [ -f "${PROCESSED_CLIENTS}" ]; then + if grep -qi "^${mac_upper}$" "${PROCESSED_CLIENTS}" 2>/dev/null; then + continue fi - continue + fi + + # Track this MAC as processed + echo "${mac_upper}" >> "${PROCESSED_CLIENTS}" + + # Find all IPs for this MAC on this bridge and prefer REACHABLE/DELAY + local all_ips=$(grep -i "${mac}" "${temp_file}" | awk '{print $1}') + local best_ip="" + + if [ -n "${all_ips}" ]; then + for candidate_ip in ${all_ips}; do + local arp_status=$(ip neigh show | grep -w "${candidate_ip}" | awk '{print $NF}' 2>/dev/null) + if [ -n "${arp_status}" ] && { [ "${arp_status}" = "REACHABLE" ] || [ "${arp_status}" = "DELAY" ]; }; then + best_ip="${candidate_ip}" + break + fi + done + # Fallback to first IP if no REACHABLE/DELAY found + [ -z "${best_ip}" ] && best_ip=$(echo "${all_ips}" | head -n1) else - clientip="$ip" - break + best_ip="${ip}" fi - done - if [ -z "$clientip" ]; then - clientip=$(cat /proc/net/arp | grep "$clientmac" | awk '{print $1}' | sort | uniq | tail -n 1) 2>/dev/null + local hostname=$(get_hostname "${mac}" "${best_ip}" "${dhcp_leases}") + # Output in pipe-delimited format: name|ip|mac + printf "%s|%s|%s\n" "${hostname:0:16}" "${best_ip}" "${mac}" >> "${temp_output}" + processed_macs_local="${processed_macs_local} ${mac_normalized}" + done < "${temp_file}" + + rm -f "${temp_file}" + + # Sort and format output + if [ -s "${temp_output}" ]; then + sort -t'|' -k${sort_field},${sort_field} "${temp_output}" | while IFS='|' read name ip mac; do + printf " %-16s | %-15s | %s\n" "${name}" "${ip}" "${mac}" + done fi + + rm -f "${temp_output}" +} - paddedclientip=$(echo "$clientip" | awk -F '.' '{printf "%03d.%03d.%03d.%03d\n", $1, $2, $3, $4}') 2>/dev/null +################################################################################ +# MAIN DISPLAY ROUTINE +################################################################################ - txtotalgb=$(echo $txtotalbytes | awk '{printf "%0.2f", $1/1024/1024/1024}') 2>/dev/null - rxtotalgb=$(echo $rxtotalbytes | awk '{printf "%0.2f", $1/1024/1024/1024}') 2>/dev/null - txratembps=$(echo $txratekbps | awk '{printf "%0.1f", $1/1000}') 2>/dev/null - rxratembps=$(echo $rxratekbps | awk '{printf "%0.1f", $1/1000}') 2>/dev/null +display_network_clients() { + local iface + local info_str + local iface_type + local band + local guest_ssid + local client_count - local found=0 - local counter=2 - while [ $counter -le $maxextractcount ] - do - local clientextract - clientextract="$(echo "$clients" | cut -d "<" -f"$counter" | cut -d ">" -f1,2)" + # Initialize processed client tracking files + > "${PROCESSED_CLIENTS}" + > "${PROCESSED_VLAN_CLIENTS}" - [ -z "$clientextract" ] && { counter=$((counter+1)); continue; } + # Read DHCP leases once for MLO/MLD awareness + local dhcp_leases=$(read_all_dhcp_leases) - local client - local mac - client="$(echo "$clientextract" | awk -F ">" '{print $1}')" - mac="$(echo "$clientextract" | awk -F ">" '{print $2}')" + # Determine sort field based on SortbyOpt + local sort_field=1 # Default: Name + if [ "${SortbyOpt}" = "IP" ]; then + sort_field=2 + elif [ "${SortbyOpt}" = "MAC" ]; then + sort_field=3 + fi - if [ "$mac" = "$macupper" ]; then - clientname="$client" - found=1 - break - fi + printf "${InvGreen} ${CClear} %-16s | %-15s | %-17s | %-8s | %5s | %5s | %7s | %7s | %3s | %s\n" \ + "Name" "IP" "MAC" "Uptime" "TX GB" "RX GB" "TX Mbps" "RX Mbps" "Sig" "Band" - counter=$((counter+1)) - done + for iface in $(get_wireless_interfaces); do + info_str=$(get_interface_info "${iface}") + iface_type=$(echo "${info_str}" | cut -d'|' -f1) + band=$(echo "${info_str}" | cut -d'|' -f2) + guest_ssid=$(echo "${info_str}" | cut -d'|' -f3) - if [ $found -ne 1 ]; then - clientname=$(echo "$dhcpleases" | grep -i "$lookup_mac" | awk '{print $4}') 2>/dev/null - if [ -z "$clientname" ] || [ "$clientname" == "*" ]; then - clientname="UNKNOWN" + [ "${iface_type}" = "unknown" ] && continue + + client_count=0 + client_list=$(get_wireless_clients "${iface}") + + if [ -n "${client_list}" ]; then + client_count=$(echo "${client_list}" | wc -l) fi - fi - if [ -n "$paddedclientip" ] && [ "$paddedclientip" != "000.000.000.000" ]; then - if grep -q "$macupper" /jffs/addons/rtrmon.d/processed_vlanclients.txt && [ "$conntime" = "STALE" ]; then - continue - else - echo "$macupper" >> /jffs/addons/rtrmon.d/processed_vlanclients.txt + # Get bridge information for display + local bridge_name=$(get_bridge_for_interface "${iface}") + local bridge_info="" + if [ -n "${bridge_name}" ]; then + bridge_info=" (Bridge: ${bridge_name})" fi - sed -i -e '/'$clientmac'/d' /jffs/addons/rtrmon.d/temparp.txt - if [ "$conntime" = "AiMesh" ]; then - echo "$clientname,$paddedclientip,$macupper,$conntime" >> /jffs/addons/rtrmon.d/vlanclients$iface.txt - else - echo "$clientname,$paddedclientip,$macupper,$conntime,$txtotalgb,$rxtotalgb,$txratembps,$rxratembps,$sigstrength,$chanspec" >> /jffs/addons/rtrmon.d/vlanclients$iface.txt + + if [ "${iface_type}" = "guest" ]; then + local content=" Guest ${band} Wi-Fi: ${guest_ssid}${bridge_info} - IFace: ${iface}" + local padded_content=$(printf "%-${HEADER_WIDTH}s" "${content}") + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite}${padded_content}${CClear}" + elif [ "${iface_type}" = "main" ]; then + # Get SSID for main wireless interfaces + local main_ssid=$(get_ssid_for_interface "${iface}") + if [ -n "${main_ssid}" ]; then + local content=" Local ${band} Wi-Fi: ${main_ssid}${bridge_info} - IFace: ${iface}" + local padded_content=$(printf "%-${HEADER_WIDTH}s" "${content}") + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite}${padded_content}${CClear}" + else + local content=" Local ${band}${bridge_info} - IFace: ${iface}" + local padded_content=$(printf "%-${HEADER_WIDTH}s" "${content}") + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite}${padded_content}${CClear}" + fi fi - fi - done - if [ -f "/jffs/addons/rtrmon.d/vlanclients$iface.txt" ]; then - if [ $vlansfound -eq 0 ]; then - sort -f -d -t ',' -k "$SortbyNum" -k 4,4 /jffs/addons/rtrmon.d/vlanclients$iface.txt 2>/dev/null | \ - awk -F',' -v OFS=',' '{if ($4 ~ /AiMesh/) {a[i++]=$0} else {print $0}} END {for (j=0; j /tmp/vlanclients_sorted.txt - mv /tmp/vlanclients_sorted.txt /jffs/addons/rtrmon.d/vlanclients$iface.txt - column -t -s',' -o' | ' -N Name,IP,MAC,Uptime,"TX GB","RX GB","TX Mbps","RX Mbps","Sig","Band" /jffs/addons/rtrmon.d/vlanclients$iface.txt | sed 's/^/ /' - else - echo -e " No Devices Connected" - fi - else - echo -e " No Devices Connected" - fi -} + if [ "${iface_type}" = "main" ] || [ "${iface_type}" = "guest" ]; then + #printf " %-16s | %-15s | %-17s | %-8s | %5s | %5s | %7s | %7s | %3s | %s\n" \ + #"Name" "IP" "MAC" "Uptime" "TX GB" "RX GB" "TX Mbps" "RX Mbps" "Sig" "Band" + if [ -n "${client_list}" ]; then + local temp_output="/tmp/netmon_client_output_$$.tmp" + > "${temp_output}" -# ------------------------------------------------------------------------------------------------------------------------- -# attachedlanclients pulls connected client info from wl, arp and nvram + for mac in ${client_list}; do + get_wireless_client_details "${iface}" "${mac}" "${dhcp_leases}" >> "${temp_output}" + done -# attachedlanclients pulls connected client info from wl, arp and nvram -attachedlanclients () -{ - maxclientcount=$(cat /jffs/addons/rtrmon.d/temparp.txt | wc -l) - rm -f /jffs/addons/rtrmon.d/clientlistbr0.txt - dhcpleases="$(read_all_dhcp_leases)" - local clients - clients="$(nvram get custom_clientlist)" - local maxextractcount - maxextractcount=$(echo "$clients" | awk -F'<' '{print NF}') - - local clientcount=0 - while [ $clientcount -le $maxclientcount ] - do - clientname="" - paddedclientip="" - clientcount=$((clientcount+1)) - local clientmac=$(cat /jffs/addons/rtrmon.d/temparp.txt | awk 'NR=='$clientcount' {print $4}') 2>/dev/null + if [ -s "${temp_output}" ]; then + sort_wireless_clients "${temp_output}" "${sort_field}" + else + echo " No wireless clients connected" + fi + rm -f "${temp_output}" + else + echo " No wireless clients connected" + fi + echo "" + fi + done - if [ -z "$clientmac" ]; then - continue - fi + # Get VLAN/AiMesh bridges from apg_ifnames (more accurate than subnet detection) + local vlan_bridges=$(get_vlan_bridges) - local macupper=$(echo "$clientmac" | tr 'a-f' 'A-F') + if [ -n "${vlan_bridges}" ]; then + for bridge in ${vlan_bridges}; do + # Get subnet for this bridge if available + local bridge_subnet=$(get_bridge_subnet "${bridge}") - if grep -qi "$macupper" /jffs/addons/rtrmon.d/processed_clients.txt 2>/dev/null; then - continue - else - echo "$macupper" >> /jffs/addons/rtrmon.d/processed_clients.txt - fi + if [ -n "${bridge_subnet}" ]; then + local content=" Local VLAN/AiMesh VLAN ${bridge_subnet} - IFace: ${bridge}" + local padded_content=$(printf "%-${HEADER_WIDTH}s" "${content}") + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite}${padded_content}${CClear}" + else + local content=" Local VLAN/AiMesh VLAN - IFace: ${bridge}" + local padded_content=$(printf "%-${HEADER_WIDTH}s" "${content}") + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite}${padded_content}${CClear}" + fi - local counter=2 - local found=0 - while [ $counter -le $maxextractcount ] - do - local clientextract - clientextract="$(echo "$clients" | cut -d "<" -f"$counter" | cut -d ">" -f1,2)" + #printf " %-16s | %-15s | %s\n" "Name" "IP" "MAC" - [ -z "$clientextract" ] && { counter=$((counter+1)); continue; } + # Use bridge-based client detection with sorting + local bridge_client_output=$(get_bridge_clients "${bridge}" "${dhcp_leases}" "${sort_field}") - clientip=$(cat /jffs/addons/rtrmon.d/temparp.txt | grep $clientmac | awk '{print $1; exit}') 2>/dev/null - paddedclientip=$(echo "${clientip}" | grep -o -E '([0-9]*\.|[0-9]*)' | awk '{printf( "%03d\n", $1)}' | tr '\n' '.' | sed 's/.$//') 2>/dev/null - if [ -z "$paddedclientip" ]; then paddedclientip="000.000.000.000"; fi + if [ -n "${bridge_client_output}" ]; then + echo "${bridge_client_output}" + else + echo " No wired clients found" + fi + echo "" + done + fi - local client - local mac - client="$(echo "$clientextract" | awk -F ">" '{print $1}')" - mac="$(echo "$clientextract" | awk -F ">" '{print $2}')" + local primary_subnet=$(get_primary_subnet) + local content=" Local LAN/Non-VLAN AiMesh - Subnet: ${primary_subnet} - IFace: br0" + local padded_content=$(printf "%-${HEADER_WIDTH}s" "${content}") + echo -e "${InvGreen} ${CClear}${InvDkGray}${CWhite}${padded_content}${CClear}" + #printf " %-16s | %-15s | %s\n" "Name" "IP" "MAC" - if [ "$mac" = "$macupper" ]; then - clientname="$client" - found=1 - break - fi + # Use bridge-based detection for br0 clients with sorting + local br0_clients=$(get_bridge_clients "br0" "${dhcp_leases}" "${sort_field}") + if [ -n "${br0_clients}" ]; then + echo "${br0_clients}" + else + echo " No wired clients found" + fi - counter=$((counter+1)) - done + # Cleanup tracking files + rm -f "${PROCESSED_CLIENTS}" "${PROCESSED_VLAN_CLIENTS}" +} - if [ $found -ne 1 ]; then - clientname=$(echo "$dhcpleases" | grep -i "$clientmac" | awk '{print $4}') - if [ -z "$clientname" ] || [ "$clientname" == "*" ]; then - clientname="UNKNOWN" - fi - fi - if [ -n "$paddedclientip" ] && [ "$paddedclientip" != "000.000.000.000" ]; then - echo "$clientname,$paddedclientip,$macupper" >> /jffs/addons/rtrmon.d/clientlistbr0.txt - fi - done +################################################################################ +# ENTRY POINT +################################################################################ + +detect_router_model + +display_network_clients | handle_pagination - if [ -f "/jffs/addons/rtrmon.d/clientlistbr0.txt" ]; then - if [ $maxclientcount -ge 1 ]; then - sort -f -d -o /jffs/addons/rtrmon.d/clientlistbr0.txt -k "$SortbyNum" -t , /jffs/addons/rtrmon.d/clientlistbr0.txt 2>/dev/null - column -t -s',' -o' | ' -N Name,IP,MAC /jffs/addons/rtrmon.d/clientlistbr0.txt | sed 's/^/ /' - else - echo -e " No Devices Connected" - fi - else - echo -e " No Devices Connected" - fi } # ------------------------------------------------------------------------------------------------------------------------- From 97782e43b50784b817c5c1a4ef6461fa95a4f645 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Sun, 14 Dec 2025 09:47:38 -0500 Subject: [PATCH 37/62] Bump version to v2.3.0b4 and update date --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f9a77a0..b46fbcb 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# RTRMON v2.2.4b2 +# RTRMON v2.3.0b4 Asus-Merlin Router Monitor by Viktor Jaep, 2022-2025 -Updated on 2025-Dec-06 +Updated on 2025-Dec-14 --- From 0406f90ff200c1af82e566f6765cd64c48470aa9 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Sun, 14 Dec 2025 09:59:43 -0500 Subject: [PATCH 38/62] Revise changelog for version 2.3.0b4 Updated changelog for version 2.3.0b4 with multiple patches and acknowledgments. --- changelog.txt | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index f9478f9..215c224 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,10 +1,26 @@ -v2.2.4b2 - (TBA) +v2.3.0b4 - (TBA) - PATCH: HUGE HUGE THANKS to both @ExtremeFiretop and @visortgw for their help getting the wired/wireless client page (#7) working again. Apparently something had broken between a firmware release that seemed to be causing some incorrect reporting on this page. Both these guys stepped in, and were able to collaboratively knock it out of the park, and get this page to report things accurately again. RTRMON wouldn't be as awesome as it is without these two incredible gentlemen! :) Thank you! + - MINOR: The fixes above led to a complete rework of the wired/wireless client page in order to + streamline and make it easier to understand and troubleshoot. As @ExtremeFiretop explained, + the methodology he was going down was causing patch after bandaid after patch as requirements + continued to change over time. This gave us a reset using all the knowledge that @ExtremeFiretop + had amassed thusfar into a new working version. Again, HUGE THANKS to both @ExtremeFiretop for + his incredible knowledge and dedication to making sure this all works as best as it can, and + for @visortgw for his relentless testing and feedback using the massively large and complex + network he has at his disposal for running RTRMON through the ringer! :) This page 7 has now + been officially "Dedicated to @ExtremeFiretop and @visortgw" for their hard work on this! + - PATCH: The new wired/wireless page 7 has column headers moved to the top of the page, instead + of at the top of each interface to reduce page draws and size. + - PATCH: The new wired/wireless page 7 now has a page run-off limiter set to 24 rows, and will + indicate if more rows are available. Pressing the (A) key will show ALL rows through each + refresh cycle, until you press (A) again to limit run-off. This prevents clutter for those + who are running large networks and would rather not deal with the constant run-off screen + refreshes. - PATCH: Thanks to a CPU temperature issue report from @fr0s7, it was found that the normal methods of finding CPU temp readings were no longer working on the RT-BE92U. @dave14305 came to the rescue, and was able to find the correct file for a temp reading. Thank you both! @@ -20,6 +36,12 @@ v2.2.4b2 - (TBA) I blame the OCD. - PATCH: Added the wireless channel spec to the table output list per @visortgw request. We may need to start widening the UI here soon! :) + - PATCH: All screens have now been widened by 10 characters to accomodate for the slightly + wider table sizes under the wired/wireless client page 7. + - PATCH: Column 1 under the wired/wireless client table is limited to 16 characters, and will + trim any client names > 16 characters. + - PATCH: NMAP results on the Network Diagnotics Page 6 are now indented by 3 characters to show + better placement under the various interfaces it is reporting on. v2.2.3 - (November 16, 2025) - PATCH: Modified how the memory stats are being captured, and is now more in line with the From b5851c9170800e580e76e8dcaa13fe525c89bf4f Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Sun, 14 Dec 2025 11:07:44 -0500 Subject: [PATCH 39/62] Update changelog.txt --- changelog.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/changelog.txt b/changelog.txt index 215c224..270bef9 100644 --- a/changelog.txt +++ b/changelog.txt @@ -8,10 +8,10 @@ v2.3.0b4 - (TBA) - MINOR: The fixes above led to a complete rework of the wired/wireless client page in order to streamline and make it easier to understand and troubleshoot. As @ExtremeFiretop explained, the methodology he was going down was causing patch after bandaid after patch as requirements - continued to change over time. This gave us a reset using all the knowledge that @ExtremeFiretop - had amassed thusfar into a new working version. Again, HUGE THANKS to both @ExtremeFiretop for - his incredible knowledge and dedication to making sure this all works as best as it can, and - for @visortgw for his relentless testing and feedback using the massively large and complex + and firmware continued to change things over time. This gave us a chance to reset using all + the knowledge that @ExtremeFiretop had amassed thus far into a new working version. Again, + HUGE THANKS to both @ExtremeFiretop for his incredible knowledge and dedication, and for + @visortgw for his relentless testing and feedback using the massively large and complex network he has at his disposal for running RTRMON through the ringer! :) This page 7 has now been officially "Dedicated to @ExtremeFiretop and @visortgw" for their hard work on this! - PATCH: The new wired/wireless page 7 has column headers moved to the top of the page, instead From 90f9023ed6f8e024eca734aade70d08012c770c0 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Sun, 14 Dec 2025 15:16:45 -0500 Subject: [PATCH 40/62] Update rtrmon.sh --- rtrmon.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/rtrmon.sh b/rtrmon.sh index 0f41382..46b60fb 100644 --- a/rtrmon.sh +++ b/rtrmon.sh @@ -24,7 +24,7 @@ export PATH="/sbin:/bin:/usr/sbin:/usr/bin:$PATH" # ------------------------------------------------------------------------------------------------------------------------- # System Variables (Do not change beyond this point or this may change the programs ability to function correctly) # ------------------------------------------------------------------------------------------------------------------------- -Version="2.3.0b4" +Version="2.3.0b5" Beta=1 ScreenshotMode=0 LOGFILE="/jffs/addons/rtrmon.d/rtrmon.log" # Logfile path/name that captures important date/time events - change @@ -135,7 +135,7 @@ w52updown="UP" w6updown="UP" w62updown="UP" SortbyOpt="Name" -PreventScrolling=1 # PreventScrolling: 0=Show all output, 1=Paginate output +PreventScrolling=0 # PreventScrolling: 0=Show all output, 1=Paginate output MaxRows=24 # MaxRows: Maximum rows to display before pausing (only used if PreventScrolling=1) ##-------------------------------------## @@ -5393,7 +5393,7 @@ sort_wireless_clients() { # Sort by the specified field (1=Name, 2=IP, 3=MAC) sort -t'|' -k${sort_field},${sort_field} "${temp_file}" | while IFS='|' read name ip mac uptime tx_gb rx_gb tx_mbps rx_mbps rssi bandwidth; do - printf " %-16s | %-15s | %-17s | %-8s | %5s | %5s | %7s | %7s | %3s | %s\n" \ + printf " %-17s | %-15s | %-17s | %-8s | %5s | %5s | %7s | %7s | %3s | %s\n" \ "${name}" "${ip}" "${mac}" "${uptime}" "${tx_gb}" "${rx_gb}" "${tx_mbps}" "${rx_mbps}" "${rssi}" "${bandwidth}" done } @@ -5467,7 +5467,7 @@ get_lan_clients() { # Sort and format output if [ -s "${temp_output}" ]; then sort -t'|' -k${sort_field},${sort_field} "${temp_output}" | while IFS='|' read name ip mac; do - printf " %-16s | %-15s | %s\n" "${name}" "${ip}" "${mac}" + printf " %-17s | %-15s | %s\n" "${name}" "${ip}" "${mac}" done fi @@ -5566,7 +5566,7 @@ get_bridge_clients() { # Sort and format output if [ -s "${temp_output}" ]; then sort -t'|' -k${sort_field},${sort_field} "${temp_output}" | while IFS='|' read name ip mac; do - printf " %-16s | %-15s | %s\n" "${name}" "${ip}" "${mac}" + printf " %-17s | %-15s | %s\n" "${name}" "${ip}" "${mac}" done fi @@ -5600,7 +5600,7 @@ display_network_clients() { sort_field=3 fi - printf "${InvGreen} ${CClear} %-16s | %-15s | %-17s | %-8s | %5s | %5s | %7s | %7s | %3s | %s\n" \ + printf "${InvGreen} ${CClear} %-17s | %-15s | %-17s | %-8s | %5s | %5s | %7s | %7s | %3s | %s\n" \ "Name" "IP" "MAC" "Uptime" "TX GB" "RX GB" "TX Mbps" "RX Mbps" "Sig" "Band" for iface in $(get_wireless_interfaces); do From 7883d8b3da8dfb31badfb63f5d14111311689e20 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Sun, 14 Dec 2025 15:18:21 -0500 Subject: [PATCH 41/62] Add details for version 2.2.3 updates Updated changelog with changes from version 2.2.3. --- changelog.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/changelog.txt b/changelog.txt index 270bef9..e7d7e19 100644 --- a/changelog.txt +++ b/changelog.txt @@ -42,6 +42,9 @@ v2.3.0b4 - (TBA) trim any client names > 16 characters. - PATCH: NMAP results on the Network Diagnotics Page 6 are now indented by 3 characters to show better placement under the various interfaces it is reporting on. + - PATCH: Per suggestions from @visortgw, changed defaults to disable screen run-off limiter, + and can be enabled anytime using (A). Also, extended column 1 that shows the device name from + 16 chars to 17 chars. Thank you! v2.2.3 - (November 16, 2025) - PATCH: Modified how the memory stats are being captured, and is now more in line with the From 9e5165cea18c1312f4010d3d64e26e67653ab708 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Sun, 14 Dec 2025 15:22:56 -0500 Subject: [PATCH 42/62] Update changelog.txt --- changelog.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index e7d7e19..b8ec454 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,4 +1,4 @@ -v2.3.0b4 - (TBA) +v2.3.0b5 - (TBA) - PATCH: HUGE HUGE THANKS to both @ExtremeFiretop and @visortgw for their help getting the wired/wireless client page (#7) working again. Apparently something had broken between a firmware release that seemed to be causing some incorrect reporting on this page. Both these From fe7b741f047fc8c9630f68ffe1e65b2c7063f852 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Sun, 14 Dec 2025 15:23:17 -0500 Subject: [PATCH 43/62] Bump version from 2.2.4 to 2.3.0 --- version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.txt b/version.txt index 530cdd9..276cbf9 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -2.2.4 +2.3.0 From 483f292c09623d4e2fe7b59de877dfad8ab9d191 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Sun, 14 Dec 2025 15:23:33 -0500 Subject: [PATCH 44/62] Update version number to v2.3.0b5 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b46fbcb..dc48887 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# RTRMON v2.3.0b4 +# RTRMON v2.3.0b5 Asus-Merlin Router Monitor by Viktor Jaep, 2022-2025 Updated on 2025-Dec-14 From 22daf5168affe1f79af3ca09b6d801995b634452 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Sun, 14 Dec 2025 16:46:33 -0500 Subject: [PATCH 45/62] Update rtrmon.sh --- rtrmon.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rtrmon.sh b/rtrmon.sh index 46b60fb..80e1194 100644 --- a/rtrmon.sh +++ b/rtrmon.sh @@ -5378,7 +5378,7 @@ get_wireless_client_details() { # Output in pipe-delimited format for sorting: name|ip|mac|other_fields printf "%s|%s|%s|%s|%s|%s|%s|%s|%s|%s\n" \ - "${hostname:0:16}" "${clientip}" "${canonupper}" "${uptime}" \ + "${hostname:0:17}" "${clientip}" "${canonupper}" "${uptime}" \ "${tx_gb}" "${rx_gb}" "${tx_mbps}" "${rx_mbps}" "${rssi:--}" "${bandwidth}" } @@ -5458,7 +5458,7 @@ get_lan_clients() { local hostname=$(get_hostname "${mac}" "${best_ip}" "${dhcp_leases}") # Output in pipe-delimited format: name|ip|mac - printf "%s|%s|%s\n" "${hostname:0:16}" "${best_ip}" "${mac}" >> "${temp_output}" + printf "%s|%s|%s\n" "${hostname:0:17}" "${best_ip}" "${mac}" >> "${temp_output}" processed_macs_local="${processed_macs_local} ${mac_normalized}" done < "${temp_file}" @@ -5557,7 +5557,7 @@ get_bridge_clients() { local hostname=$(get_hostname "${mac}" "${best_ip}" "${dhcp_leases}") # Output in pipe-delimited format: name|ip|mac - printf "%s|%s|%s\n" "${hostname:0:16}" "${best_ip}" "${mac}" >> "${temp_output}" + printf "%s|%s|%s\n" "${hostname:0:17}" "${best_ip}" "${mac}" >> "${temp_output}" processed_macs_local="${processed_macs_local} ${mac_normalized}" done < "${temp_file}" From 138ae94567b6f4169f7d106b10fac421a436960f Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Mon, 15 Dec 2025 18:49:01 -0500 Subject: [PATCH 46/62] Update rtrmon.sh --- rtrmon.sh | 79 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 60 insertions(+), 19 deletions(-) diff --git a/rtrmon.sh b/rtrmon.sh index 80e1194..8e3ea39 100644 --- a/rtrmon.sh +++ b/rtrmon.sh @@ -15,7 +15,7 @@ # # Please use the 'sh rtrmon.sh -setup' command to configure the necessary parameters that match your environment the best! # -# Last Modified: 2025-Dec-14 +# Last Modified: 2025-Dec-15 ########################################################################################################################### #Preferred standard router binaries path @@ -24,7 +24,7 @@ export PATH="/sbin:/bin:/usr/sbin:/usr/bin:$PATH" # ------------------------------------------------------------------------------------------------------------------------- # System Variables (Do not change beyond this point or this may change the programs ability to function correctly) # ------------------------------------------------------------------------------------------------------------------------- -Version="2.3.0b5" +Version="2.3.0b6" Beta=1 ScreenshotMode=0 LOGFILE="/jffs/addons/rtrmon.d/rtrmon.log" # Logfile path/name that captures important date/time events - change @@ -543,7 +543,7 @@ progressbaroverride() then case "$key_press" in [Aa]) if [ "$PreventScrolling" = "1" ]; then PreventScrolling=0; elif [ "$PreventScrolling" = "0" ]; then PreventScrolling=1; fi; - timerReset=1;; + timerReset=1;; [Cc]) QueueNetworkConn=1 echo -e "${CClear}[Queuing Network Connection Stats] "; sleep 1; NextPage=6; timerReset=1 @@ -4937,6 +4937,22 @@ get_ssid_for_interface() { echo "${ssid}" } +# Sort IP addresses numerically by converting to zero-padded format +sort_by_ip() { + local temp_file="$1" + + # Add zero-padded IP as first field for sorting, then sort, then remove it + awk -F'|' '{ + split($2, octets, "."); # Split IP address into octets (field 2 is the IP) + if (octets[1] != "" && octets[2] != "" && octets[3] != "" && octets[4] != "") { + padded_ip = sprintf("%03d.%03d.%03d.%03d", octets[1], octets[2], octets[3], octets[4]); # Create zero-padded version for sorting (e.g., 192.168.050.002) + } else { + padded_ip = "999.999.999.999"; # Handle "Unknown" or malformed IPs - sort them last + } + print padded_ip "|" $0; + }' "${temp_file}" | sort -t'|' -k1,1 | cut -d'|' -f2- +} + # Pagination control function # Manages output display with optional row limiting handle_pagination() { @@ -5378,8 +5394,8 @@ get_wireless_client_details() { # Output in pipe-delimited format for sorting: name|ip|mac|other_fields printf "%s|%s|%s|%s|%s|%s|%s|%s|%s|%s\n" \ - "${hostname:0:17}" "${clientip}" "${canonupper}" "${uptime}" \ - "${tx_gb}" "${rx_gb}" "${tx_mbps}" "${rx_mbps}" "${rssi:--}" "${bandwidth}" + "${hostname:0:17}" "${clientip}" "${canonupper}" "${uptime:0:8}" \ + "${tx_gb:0:5}" "${rx_gb:0:5}" "${tx_mbps:0:7}" "${rx_mbps:0:7}" "${rssi:0:3}" "${bandwidth:0:7}" } # Sort and format wireless client output @@ -5392,10 +5408,19 @@ sort_wireless_clients() { fi # Sort by the specified field (1=Name, 2=IP, 3=MAC) - sort -t'|' -k${sort_field},${sort_field} "${temp_file}" | while IFS='|' read name ip mac uptime tx_gb rx_gb tx_mbps rx_mbps rssi bandwidth; do - printf " %-17s | %-15s | %-17s | %-8s | %5s | %5s | %7s | %7s | %3s | %s\n" \ - "${name}" "${ip}" "${mac}" "${uptime}" "${tx_gb}" "${rx_gb}" "${tx_mbps}" "${rx_mbps}" "${rssi}" "${bandwidth}" - done + if [ "${sort_field}" -eq 2 ]; then + # IP sorting - use custom IP sort for proper numeric ordering + sort_by_ip "${temp_file}" | while IFS='|' read name ip mac uptime tx_gb rx_gb tx_mbps rx_mbps rssi bandwidth; do + printf " %-17s | %-15s | %-17s | %-8s | %5s | %5s | %7s | %7s | %3s | %s\n" \ + "${name}" "${ip}" "${mac}" "${uptime}" "${tx_gb}" "${rx_gb}" "${tx_mbps}" "${rx_mbps}" "${rssi}" "${bandwidth}" + done + else + # Name or MAC sorting - use regular sort + sort -t'|' -k${sort_field},${sort_field} "${temp_file}" | while IFS='|' read name ip mac uptime tx_gb rx_gb tx_mbps rx_mbps rssi bandwidth; do + printf " %-17s | %-15s | %-17s | %-8s | %5s | %5s | %7s | %7s | %3s | %s\n" \ + "${name}" "${ip}" "${mac}" "${uptime}" "${tx_gb}" "${rx_gb}" "${tx_mbps}" "${rx_mbps}" "${rssi}" "${bandwidth}" + done + fi } get_lan_clients() { @@ -5466,9 +5491,17 @@ get_lan_clients() { # Sort and format output if [ -s "${temp_output}" ]; then - sort -t'|' -k${sort_field},${sort_field} "${temp_output}" | while IFS='|' read name ip mac; do - printf " %-17s | %-15s | %s\n" "${name}" "${ip}" "${mac}" - done + if [ "${sort_field}" -eq 2 ]; then + # IP sorting - use custom IP sort + sort_by_ip "${temp_output}" | while IFS='|' read name ip mac; do + printf " %-17s | %-15s | %s\n" "${name}" "${ip}" "${mac}" + done + else + # Name or MAC sorting - use regular sort + sort -t'|' -k${sort_field},${sort_field} "${temp_output}" | while IFS='|' read name ip mac; do + printf " %-17s | %-15s | %s\n" "${name}" "${ip}" "${mac}" + done + fi fi rm -f "${temp_output}" @@ -5565,9 +5598,17 @@ get_bridge_clients() { # Sort and format output if [ -s "${temp_output}" ]; then - sort -t'|' -k${sort_field},${sort_field} "${temp_output}" | while IFS='|' read name ip mac; do - printf " %-17s | %-15s | %s\n" "${name}" "${ip}" "${mac}" - done + if [ "${sort_field}" -eq 2 ]; then + # IP sorting - use custom IP sort + sort_by_ip "${temp_output}" | while IFS='|' read name ip mac; do + printf " %-17s | %-15s | %s\n" "${name}" "${ip}" "${mac}" + done + else + # Name or MAC sorting - use regular sort + sort -t'|' -k${sort_field},${sort_field} "${temp_output}" | while IFS='|' read name ip mac; do + printf " %-17s | %-15s | %s\n" "${name}" "${ip}" "${mac}" + done + fi fi rm -f "${temp_output}" @@ -5744,7 +5785,7 @@ GetVPNWGIPCITY() NVRAMVPN1IP=$(ping -c 1 -w 1 $NVRAMVPN1ADDR | awk -F '[()]' '/PING/ { print $2}') if [ "$NVRAMVPN1ADDR" != "$oldvpn1ADDR" ]; then - if [ "$VPNSite2Site" == "1" ]; then + if [ "$VPNSite2Site" == "1" ]; then oldvpn1ip=$NVRAMVPN1IP else oldvpn1ip=$(curl --silent --fail --interface $TUN1 --request GET --url https://ipv4.icanhazip.com) @@ -5781,7 +5822,7 @@ GetVPNWGIPCITY() NVRAMVPN2IP=$(ping -c 1 -w 1 $NVRAMVPN2ADDR | awk -F '[()]' '/PING/ { print $2}') if [ "$NVRAMVPN2ADDR" != "$oldvpn2ADDR" ]; then - if [ "$VPNSite2Site" == "1" ]; then + if [ "$VPNSite2Site" == "1" ]; then oldvpn2ip=$NVRAMVPN2IP else oldvpn2ip=$(curl --silent --fail --interface $TUN2 --request GET --url https://ipv4.icanhazip.com) @@ -5818,7 +5859,7 @@ GetVPNWGIPCITY() NVRAMVPN3IP=$(ping -c 1 -w 1 $NVRAMVPN3ADDR | awk -F '[()]' '/PING/ { print $2}') if [ "$NVRAMVPN3ADDR" != "$oldvpn3ADDR" ]; then - if [ "$VPNSite2Site" == "1" ]; then + if [ "$VPNSite2Site" == "1" ]; then oldvpn3ip=$NVRAMVPN3IP else oldvpn3ip=$(curl --silent --fail --interface $TUN3 --request GET --url https://ipv4.icanhazip.com) @@ -5892,7 +5933,7 @@ GetVPNWGIPCITY() NVRAMVPN5IP=$(ping -c 1 -w 1 $NVRAMVPN5ADDR | awk -F '[()]' '/PING/ { print $2}') if [ "$NVRAMVPN5ADDR" != "$oldvpn5ADDR" ]; then - if [ "$VPNSite2Site" == "1" ]; then + if [ "$VPNSite2Site" == "1" ]; then oldvpn5ip=$NVRAMVPN5IP else oldvpn5ip=$(curl --silent --fail --interface $TUN5 --request GET --url https://ipv4.icanhazip.com) From aa5434b12bb4dbaaf0a1ef4d075cf300c87750d4 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Mon, 15 Dec 2025 18:50:06 -0500 Subject: [PATCH 47/62] Update changelog for v2.3.0b6 release Updated version from v2.3.0b5 to v2.3.0b6 and added new patch notes. --- changelog.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index b8ec454..0b78e50 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,4 +1,4 @@ -v2.3.0b5 - (TBA) +v2.3.0b6 - (TBA) - PATCH: HUGE HUGE THANKS to both @ExtremeFiretop and @visortgw for their help getting the wired/wireless client page (#7) working again. Apparently something had broken between a firmware release that seemed to be causing some incorrect reporting on this page. Both these @@ -45,6 +45,8 @@ v2.3.0b5 - (TBA) - PATCH: Per suggestions from @visortgw, changed defaults to disable screen run-off limiter, and can be enabled anytime using (A). Also, extended column 1 that shows the device name from 16 chars to 17 chars. Thank you! + - PATCH: Added a better way to sort IP addresses, so they are accurately sorting from low to high. + Thanks to @CaptainSTX for the nudge! :) v2.2.3 - (November 16, 2025) - PATCH: Modified how the memory stats are being captured, and is now more in line with the From 2ec198b8e660fd33ecef6c85e65c1d9282e6e228 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Mon, 15 Dec 2025 18:56:49 -0500 Subject: [PATCH 48/62] Update changelog.txt --- changelog.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/changelog.txt b/changelog.txt index 0b78e50..1f0bb03 100644 --- a/changelog.txt +++ b/changelog.txt @@ -47,6 +47,8 @@ v2.3.0b6 - (TBA) 16 chars to 17 chars. Thank you! - PATCH: Added a better way to sort IP addresses, so they are accurately sorting from low to high. Thanks to @CaptainSTX for the nudge! :) + - PATCH: Specified max length values for the remainder of the wireless client table items, so that + they will truncate should they go over their max length as to not skew the table layout. v2.2.3 - (November 16, 2025) - PATCH: Modified how the memory stats are being captured, and is now more in line with the From ab308fa23277c1df8651131b33fd277ad5ef1d0b Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Fri, 19 Dec 2025 07:13:20 -0500 Subject: [PATCH 49/62] Update rtrmon.sh --- rtrmon.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/rtrmon.sh b/rtrmon.sh index 8e3ea39..04ccd40 100644 --- a/rtrmon.sh +++ b/rtrmon.sh @@ -745,17 +745,16 @@ timerReset=1 trimlogs() { - if [ "$LOGSIZE" -gt 0 ] then - currlogsize=$(wc -l $LOGFILE | awk '{ print $1 }' ) # Determine the number of rows in the log + currlogsize="$(wc -l "$LOGFILE" | awk '{ print $1 }')" # Determine the number of rows in the log if [ "$currlogsize" -gt "$LOGSIZE" ] # If it's bigger than the max allowed, tail/trim it! - then - echo "$(tail -$LOGSIZE $LOGFILE)" > $LOGFILE - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: Trimmed the log file down to $LOGSIZE lines" >> $LOGFILE + then + tail -"$LOGSIZE" "$LOGFILE" > "${LOGFILE}.tmp" + mv "${LOGFILE}.tmp" "$LOGFILE" + echo "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: Trimmed the log file down to $LOGSIZE lines" >> "$LOGFILE" fi - fi } From 437d19319b1a85a16a95ba37730fbf1ec717cbf1 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Fri, 19 Dec 2025 07:13:32 -0500 Subject: [PATCH 50/62] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dc48887..4388749 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# RTRMON v2.3.0b5 +# RTRMON v2.3.0b6 Asus-Merlin Router Monitor by Viktor Jaep, 2022-2025 Updated on 2025-Dec-14 From 8cc836a2a8dde0b42a27ab42b9508a118d84635d Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Wed, 7 Jan 2026 21:16:51 -0500 Subject: [PATCH 51/62] Update rtrmon.sh --- rtrmon.sh | 142 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 93 insertions(+), 49 deletions(-) diff --git a/rtrmon.sh b/rtrmon.sh index 04ccd40..3858a86 100644 --- a/rtrmon.sh +++ b/rtrmon.sh @@ -1,6 +1,6 @@ #!/bin/sh -# RTRMON - Asus-Merlin Router Monitor by Viktor Jaep, 2022-2025 +# RTRMON - Asus-Merlin Router Monitor by Viktor Jaep, 2022-2026 # # RTRMON is a shell script that provides near-realtime stats about your Asus-Merlin firmware router. Instead of having to # find this information on various different screens or apps, this tool was built to bring all this info together in one @@ -15,7 +15,7 @@ # # Please use the 'sh rtrmon.sh -setup' command to configure the necessary parameters that match your environment the best! # -# Last Modified: 2025-Dec-15 +# Last Modified: 2026-Jan-7 ########################################################################################################################### #Preferred standard router binaries path @@ -24,7 +24,7 @@ export PATH="/sbin:/bin:/usr/sbin:/usr/bin:$PATH" # ------------------------------------------------------------------------------------------------------------------------- # System Variables (Do not change beyond this point or this may change the programs ability to function correctly) # ------------------------------------------------------------------------------------------------------------------------- -Version="2.3.0b6" +Version="2.3.0b7" Beta=1 ScreenshotMode=0 LOGFILE="/jffs/addons/rtrmon.d/rtrmon.log" # Logfile path/name that captures important date/time events - change @@ -2175,27 +2175,41 @@ calculatestats() # Network - Wifi - Traffic # Standard Dual Band - new24rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname24/statistics/rx_bytes)" - new24txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname24/statistics/tx_bytes)" - new5rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname5/statistics/rx_bytes)" - new5txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname5/statistics/tx_bytes)" + #new24rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname24/statistics/rx_bytes)" + #new24txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname24/statistics/tx_bytes)" + #new5rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname5/statistics/rx_bytes)" + #new5txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname5/statistics/tx_bytes)" + + new24rxbytes="$(wl -i $ifname24 counters | grep -o 'rxbyte [0-9]*' | cut -d' ' -f2)" + new24txbytes="$(wl -i $ifname24 counters | grep -o 'txbyte [0-9]*' | cut -d' ' -f2)" + new5rxbytes="$(wl -i $ifname5 counters | grep -o 'rxbyte [0-9]*' | cut -d' ' -f2)" + new5txbytes="$(wl -i $ifname5 counters | grep -o 'txbyte [0-9]*' | cut -d' ' -f2)" # Tri or Quad Band 5GHz if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ] then - new52rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname52/statistics/rx_bytes)" - new52txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname52/statistics/tx_bytes)" + #new52rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname52/statistics/rx_bytes)" + #new52txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname52/statistics/tx_bytes)" + + new52rxbytes="$(wl -i $ifname52 counters | grep -o 'rxbyte [0-9]*' | cut -d' ' -f2)" + new52txbytes="$(wl -i $ifname52 counters | grep -o 'txbyte [0-9]*' | cut -d' ' -f2)" fi # Tri or Quad Band 6GHz if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ] then - new6rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname6/statistics/rx_bytes)" - new6txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname6/statistics/tx_bytes)" + #new6rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname6/statistics/rx_bytes)" + #new6txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname6/statistics/tx_bytes)" + + new6rxbytes="$(wl -i $ifname6 counters | grep -o 'rxbyte [0-9]*' | cut -d' ' -f2)" + new6txbytes="$(wl -i $ifname6 counters | grep -o 'txbyte [0-9]*' | cut -d' ' -f2)" fi if [ "$FourBandCustom56624" == "True" ] then - new62rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname62/statistics/rx_bytes)" - new62txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname62/statistics/tx_bytes)" + #new62rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname62/statistics/rx_bytes)" + #new62txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$ifname62/statistics/tx_bytes)" + + new62rxbytes="$(wl -i $ifname62 counters | grep -o 'rxbyte [0-9]*' | cut -d' ' -f2)" + new62txbytes="$(wl -i $ifname62 counters | grep -o 'txbyte [0-9]*' | cut -d' ' -f2)" fi # Network - LAN - Traffic @@ -4923,7 +4937,7 @@ get_band_from_interface() { get_ssid_for_interface() { local iface="$1" local ssid="" - + # Find the wl unit number for this interface for wl_unit in 0 1 2 3; do local unit_iface=$(${NVRAM} get wl${wl_unit}_ifname 2>/dev/null) @@ -4932,18 +4946,18 @@ get_ssid_for_interface() { break fi done - + echo "${ssid}" } # Sort IP addresses numerically by converting to zero-padded format sort_by_ip() { local temp_file="$1" - + # Add zero-padded IP as first field for sorting, then sort, then remove it awk -F'|' '{ split($2, octets, "."); # Split IP address into octets (field 2 is the IP) - if (octets[1] != "" && octets[2] != "" && octets[3] != "" && octets[4] != "") { + if (octets[1] != "" && octets[2] != "" && octets[3] != "" && octets[4] != "") { padded_ip = sprintf("%03d.%03d.%03d.%03d", octets[1], octets[2], octets[3], octets[4]); # Create zero-padded version for sorting (e.g., 192.168.050.002) } else { padded_ip = "999.999.999.999"; # Handle "Unknown" or malformed IPs - sort them last @@ -4957,30 +4971,30 @@ sort_by_ip() { handle_pagination() { local line_count=0 local total_lines=0 - + # If pagination is disabled, just output everything if [ "${PreventScrolling}" -eq 0 ]; then cat return fi - + # Count total lines first local temp_file="/tmp/netmon_paginate_$$.tmp" cat > "${temp_file}" total_lines=$(wc -l < "${temp_file}") - + # If total lines is less than MaxRows, just display everything if [ ${total_lines} -le ${MaxRows} ]; then cat "${temp_file}" rm -f "${temp_file}" return fi - + # Display with pagination - stop at MaxRows while IFS= read -r line; do echo "${line}" line_count=$((line_count + 1)) - + if [ ${line_count} -ge ${MaxRows} ]; then local remaining=$((total_lines - line_count)) if [ ${remaining} -gt 0 ]; then @@ -4991,7 +5005,7 @@ handle_pagination() { fi fi done < "${temp_file}" - + rm -f "${temp_file}" } @@ -5401,11 +5415,11 @@ get_wireless_client_details() { sort_wireless_clients() { local temp_file="$1" local sort_field="$2" - + if [ ! -s "${temp_file}" ]; then return fi - + # Sort by the specified field (1=Name, 2=IP, 3=MAC) if [ "${sort_field}" -eq 2 ]; then # IP sorting - use custom IP sort for proper numeric ordering @@ -5487,7 +5501,7 @@ get_lan_clients() { done < "${temp_file}" rm -f "${temp_file}" - + # Sort and format output if [ -s "${temp_output}" ]; then if [ "${sort_field}" -eq 2 ]; then @@ -5502,7 +5516,7 @@ get_lan_clients() { done fi fi - + rm -f "${temp_output}" } @@ -5594,7 +5608,7 @@ get_bridge_clients() { done < "${temp_file}" rm -f "${temp_file}" - + # Sort and format output if [ -s "${temp_output}" ]; then if [ "${sort_field}" -eq 2 ]; then @@ -5609,7 +5623,7 @@ get_bridge_clients() { done fi fi - + rm -f "${temp_output}" } @@ -6783,21 +6797,36 @@ trap '_IgnoreKeypresses_ OFF ; exit 0' EXIT INT QUIT ABRT TERM ifname5=$($timeoutcmd$timeoutsec nvram get wl1_ifname) fi - old24rxbytes="$(cat /sys/class/net/$ifname24/statistics/rx_bytes)" - old24txbytes="$(cat /sys/class/net/$ifname24/statistics/tx_bytes)" - old5rxbytes="$(cat /sys/class/net/$ifname5/statistics/rx_bytes)" - old5txbytes="$(cat /sys/class/net/$ifname5/statistics/tx_bytes)" + #old24rxbytes="$(cat /sys/class/net/$ifname24/statistics/rx_bytes)" + #old24txbytes="$(cat /sys/class/net/$ifname24/statistics/tx_bytes)" + #old5rxbytes="$(cat /sys/class/net/$ifname5/statistics/rx_bytes)" + #old5txbytes="$(cat /sys/class/net/$ifname5/statistics/tx_bytes)" + + old24rxbytes="$(wl -i $ifname24 counters | grep -o 'rxbyte [0-9]*' | cut -d' ' -f2)" + old24txbytes="$(wl -i $ifname24 counters | grep -o 'txbyte [0-9]*' | cut -d' ' -f2)" + old5rxbytes="$(wl -i $ifname5 counters | grep -o 'rxbyte [0-9]*' | cut -d' ' -f2)" + old5txbytes="$(wl -i $ifname5 counters | grep -o 'txbyte [0-9]*' | cut -d' ' -f2)" + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then - old52rxbytes="$(cat /sys/class/net/$ifname52/statistics/rx_bytes)" - old52txbytes="$(cat /sys/class/net/$ifname52/statistics/tx_bytes)" + #old52rxbytes="$(cat /sys/class/net/$ifname52/statistics/rx_bytes)" + #old52txbytes="$(cat /sys/class/net/$ifname52/statistics/tx_bytes)" + + old52rxbytes="$(wl -i $ifname52 counters | grep -o 'rxbyte [0-9]*' | cut -d' ' -f2)" + old52txbytes="$(wl -i $ifname52 counters | grep -o 'txbyte [0-9]*' | cut -d' ' -f2)" fi if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then - old6rxbytes="$(cat /sys/class/net/$ifname6/statistics/rx_bytes)" - old6txbytes="$(cat /sys/class/net/$ifname6/statistics/tx_bytes)" + #old6rxbytes="$(cat /sys/class/net/$ifname6/statistics/rx_bytes)" + #old6txbytes="$(cat /sys/class/net/$ifname6/statistics/tx_bytes)" + + old6rxbytes="$(wl -i $ifname6 counters | grep -o 'rxbyte [0-9]*' | cut -d' ' -f2)" + old6txbytes="$(wl -i $ifname6 counters | grep -o 'txbyte [0-9]*' | cut -d' ' -f2)" fi if [ "$FourBandCustom56624" == "True" ]; then - old62rxbytes="$(cat /sys/class/net/$ifname62/statistics/rx_bytes)" - old62txbytes="$(cat /sys/class/net/$ifname62/statistics/tx_bytes)" + #old62rxbytes="$(cat /sys/class/net/$ifname62/statistics/rx_bytes)" + #old62txbytes="$(cat /sys/class/net/$ifname62/statistics/tx_bytes)" + + old62rxbytes="$(wl -i $ifname62 counters | grep -o 'rxbyte [0-9]*' | cut -d' ' -f2)" + old62txbytes="$(wl -i $ifname62 counters | grep -o 'txbyte [0-9]*' | cut -d' ' -f2)" fi oldlanrxbytes="$(cat /sys/class/net/br0/statistics/rx_bytes)" oldlantxbytes="$(cat /sys/class/net/br0/statistics/tx_bytes)" @@ -6904,21 +6933,36 @@ do oldwanrxbytes="$(cat /sys/class/net/$WANIFNAME/statistics/rx_bytes)" oldwantxbytes="$(cat /sys/class/net/$WANIFNAME/statistics/tx_bytes)" fi - old24rxbytes="$(cat /sys/class/net/$ifname24/statistics/rx_bytes)" - old24txbytes="$(cat /sys/class/net/$ifname24/statistics/tx_bytes)" - old5rxbytes="$(cat /sys/class/net/$ifname5/statistics/rx_bytes)" - old5txbytes="$(cat /sys/class/net/$ifname5/statistics/tx_bytes)" + #old24rxbytes="$(cat /sys/class/net/$ifname24/statistics/rx_bytes)" + #old24txbytes="$(cat /sys/class/net/$ifname24/statistics/tx_bytes)" + #old5rxbytes="$(cat /sys/class/net/$ifname5/statistics/rx_bytes)" + #old5txbytes="$(cat /sys/class/net/$ifname5/statistics/tx_bytes)" + + old24rxbytes="$(wl -i $ifname24 counters | grep -o 'rxbyte [0-9]*' | cut -d' ' -f2)" + old24txbytes="$(wl -i $ifname24 counters | grep -o 'txbyte [0-9]*' | cut -d' ' -f2)" + old5rxbytes="$(wl -i $ifname5 counters | grep -o 'rxbyte [0-9]*' | cut -d' ' -f2)" + old5txbytes="$(wl -i $ifname5 counters | grep -o 'txbyte [0-9]*' | cut -d' ' -f2)" + if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2455" == "True" ]; then - old52rxbytes="$(cat /sys/class/net/$ifname52/statistics/rx_bytes)" - old52txbytes="$(cat /sys/class/net/$ifname52/statistics/tx_bytes)" + #old52rxbytes="$(cat /sys/class/net/$ifname52/statistics/rx_bytes)" + #old52txbytes="$(cat /sys/class/net/$ifname52/statistics/tx_bytes)" + + old52rxbytes="$(wl -i $ifname52 counters | grep -o 'rxbyte [0-9]*' | cut -d' ' -f2)" + old52txbytes="$(wl -i $ifname52 counters | grep -o 'txbyte [0-9]*' | cut -d' ' -f2)" fi if [ "$FourBandCustom55624" == "True" ] || [ "$ThreeBand2456" == "True" ] || [ "$FourBandCustom56624" == "True" ]; then - old6rxbytes="$(cat /sys/class/net/$ifname6/statistics/rx_bytes)" - old6txbytes="$(cat /sys/class/net/$ifname6/statistics/tx_bytes)" + #old6rxbytes="$(cat /sys/class/net/$ifname6/statistics/rx_bytes)" + #old6txbytes="$(cat /sys/class/net/$ifname6/statistics/tx_bytes)" + + old6rxbytes="$(wl -i $ifname6 counters | grep -o 'rxbyte [0-9]*' | cut -d' ' -f2)" + old6txbytes="$(wl -i $ifname6 counters | grep -o 'txbyte [0-9]*' | cut -d' ' -f2)" fi if [ "$FourBandCustom56624" == "True" ]; then - old62rxbytes="$(cat /sys/class/net/$ifname62/statistics/rx_bytes)" - old62txbytes="$(cat /sys/class/net/$ifname62/statistics/tx_bytes)" + #old62rxbytes="$(cat /sys/class/net/$ifname62/statistics/rx_bytes)" + #old62txbytes="$(cat /sys/class/net/$ifname62/statistics/tx_bytes)" + + old62rxbytes="$(wl -i $ifname62 counters | grep -o 'rxbyte [0-9]*' | cut -d' ' -f2)" + old62txbytes="$(wl -i $ifname62 counters | grep -o 'txbyte [0-9]*' | cut -d' ' -f2)" fi oldlanrxbytes="$(cat /sys/class/net/br0/statistics/rx_bytes)" oldlantxbytes="$(cat /sys/class/net/br0/statistics/tx_bytes)" From 1174194600486de5d1a1df6d3bb9a0d49e72519e Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Wed, 7 Jan 2026 21:19:00 -0500 Subject: [PATCH 52/62] Update changelog.txt --- changelog.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index 1f0bb03..d40c16d 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,4 +1,4 @@ -v2.3.0b6 - (TBA) +v2.3.0b7 - (TBA) - PATCH: HUGE HUGE THANKS to both @ExtremeFiretop and @visortgw for their help getting the wired/wireless client page (#7) working again. Apparently something had broken between a firmware release that seemed to be causing some incorrect reporting on this page. Both these @@ -49,6 +49,10 @@ v2.3.0b6 - (TBA) Thanks to @CaptainSTX for the nudge! :) - PATCH: Specified max length values for the remainder of the wireless client table items, so that they will truncate should they go over their max length as to not skew the table layout. + - PATCH: Fixed the Wi-Fi stats page, as it was using an older method of collecting interface stats. + With the newer routers implementing per-SSID/VLAN accounting at the driver level, the parent + interface (ex: wl0) no longer accumulates statistics directly. This new method of capturing this + info should be backwards compatiable with other routers and older firmware. TBD! ;) v2.2.3 - (November 16, 2025) - PATCH: Modified how the memory stats are being captured, and is now more in line with the From 85d2d44596664712c06d30625c02cf83791e6293 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Wed, 7 Jan 2026 21:20:02 -0500 Subject: [PATCH 53/62] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4388749..33551f9 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# RTRMON v2.3.0b6 -Asus-Merlin Router Monitor by Viktor Jaep, 2022-2025 +# RTRMON v2.3.0b7 +Asus-Merlin Router Monitor by Viktor Jaep, 2022-2026 -Updated on 2025-Dec-14 +Updated on 2026-Jan-7 --- From cf8eec47d27e864d4cc1cd97658a16b066446742 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Thu, 8 Jan 2026 20:54:09 -0500 Subject: [PATCH 54/62] Update changelog.txt --- changelog.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/changelog.txt b/changelog.txt index d40c16d..13475f1 100644 --- a/changelog.txt +++ b/changelog.txt @@ -53,6 +53,10 @@ v2.3.0b7 - (TBA) With the newer routers implementing per-SSID/VLAN accounting at the driver level, the parent interface (ex: wl0) no longer accumulates statistics directly. This new method of capturing this info should be backwards compatiable with other routers and older firmware. TBD! ;) + - PATCH: Changed some of the wording within the script from "iMesh" to "AiMesh" as what it is + formally known as today. Also, fixed the commandline instructions to indicate that pages 1-7 + are able to be called from a "rtrmon -monitor 3" optional type of command to jump right to that + particular page. Thanks @jksmurf! v2.2.3 - (November 16, 2025) - PATCH: Modified how the memory stats are being captured, and is now more in line with the From e299facd78dc6bb13766c093b41d7cca466a677d Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Thu, 8 Jan 2026 20:55:51 -0500 Subject: [PATCH 55/62] Update changelog.txt --- changelog.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/changelog.txt b/changelog.txt index 13475f1..60a50d3 100644 --- a/changelog.txt +++ b/changelog.txt @@ -53,8 +53,8 @@ v2.3.0b7 - (TBA) With the newer routers implementing per-SSID/VLAN accounting at the driver level, the parent interface (ex: wl0) no longer accumulates statistics directly. This new method of capturing this info should be backwards compatiable with other routers and older firmware. TBD! ;) - - PATCH: Changed some of the wording within the script from "iMesh" to "AiMesh" as what it is - formally known as today. Also, fixed the commandline instructions to indicate that pages 1-7 + - PATCH: Changed some of the wording within the script from "iMesh" to "AiMesh" as this is what it + is formally known as today. Also, fixed the commandline instructions to indicate that pages 1-7 are able to be called from a "rtrmon -monitor 3" optional type of command to jump right to that particular page. Thanks @jksmurf! From 802554eaa944caf746c593119aa76b72ec7a6137 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Thu, 8 Jan 2026 20:59:01 -0500 Subject: [PATCH 56/62] Update rtrmon.sh --- rtrmon.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/rtrmon.sh b/rtrmon.sh index 3858a86..941c38b 100644 --- a/rtrmon.sh +++ b/rtrmon.sh @@ -814,7 +814,7 @@ vconfig() echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(11)${CClear} : WAN0 Interface Override? : ${CGreen}$WANOverride" if [ "$WAN0AltModes" == "0" ]; then WAN0AltModesdisp="No"; else WAN0AltModesdisp="Yes"; fi - echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(12)${CClear} : Mark Router As iMesh Node/Repeater/Bridge? : ${CGreen}$WAN0AltModesdisp" + echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(12)${CClear} : Mark Router As AiMesh Node/Repeater/Bridge? : ${CGreen}$WAN0AltModesdisp" if [ "$VPNSite2Site" == "0" ]; then VPNSite2Sitedisp="No"; else VPNSite2Sitedisp="Yes"; fi echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(13)${CClear} : Mark Router As VPN Site-To-Site Only? : ${CGreen}$VPNSite2Sitedisp" echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(14)${CClear} : Custom Event Log Size? : ${CGreen}$LOGSIZE" @@ -1207,10 +1207,10 @@ vconfig() 12) # ----------------------------------------------------------------------------------------- clear - echo -e "${InvGreen} ${InvDkGray}${CWhite} Mark Router As iMesh Node/Repeater/Bridge ${CClear}" + echo -e "${InvGreen} ${InvDkGray}${CWhite} Mark Router As AiMesh Node/Repeater/Bridge ${CClear}" echo -e "${InvGreen} ${CClear}" echo -e "${InvGreen} ${CClear} Please indicate if you would like to mark that this router is being used as an${CClear}" - echo -e "${InvGreen} ${CClear} iMesh Node, Repeater or Bridge operating mode. In cases like this, the WAN0${CClear}" + echo -e "${InvGreen} ${CClear} AiMesh Node, Repeater or Bridge operating mode. In cases like this, the WAN0${CClear}" echo -e "${InvGreen} ${CClear} interface will be non-functional, and will be omitted from being captured by${CClear}" echo -e "${InvGreen} ${CClear} RTRMON's stats.${CClear}" echo -e "${InvGreen} ${CClear}" @@ -1220,10 +1220,10 @@ vconfig() if [ "$WAN0AltModes" == "0" ]; then WAN0AltModesdisp="No"; else WAN0AltModesdisp="Yes"; fi echo -e "${CClear}Current: ${CGreen}$WAN0AltModesdisp${CClear}" echo "" - echo -e "Is this router an iMesh Node/Repeater/Bridge?${CClear}" + echo -e "Is this router an AiMesh Node/Repeater/Bridge?${CClear}" if promptyn "[y/n]: "; then WAN0AltModes=1 - echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: This device's operating mode was marked as an iMesh Node/AP/Repeater/Bridge." >> $LOGFILE + echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: This device's operating mode was marked as an AiMesh Node/AP/Repeater/Bridge." >> $LOGFILE else WAN0AltModes=0 echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: This device's operating mode was marked as a Router." >> $LOGFILE @@ -6497,7 +6497,7 @@ trap '_IgnoreKeypresses_ OFF ; exit 0' EXIT INT QUIT ABRT TERM echo " -uninstall (uninstall utility)" echo " -screen (normal router monitoring using the screen utility)" echo " -monitor (normal router monitoring operations)" - echo " -screen/-monitor X (X = display screen 1-6 upon execution)" + echo " -screen/-monitor X (X = display screen 1-7 upon execution)" echo " -screen -now (bypass screen instructions and 5 sec timer)" echo "" echo " Examples:" From 364370b0dfdcef39754f61eaf38b9bb55dc45291 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Fri, 9 Jan 2026 05:29:43 -0500 Subject: [PATCH 57/62] Update rtrmon.sh --- rtrmon.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtrmon.sh b/rtrmon.sh index 941c38b..76a43f6 100644 --- a/rtrmon.sh +++ b/rtrmon.sh @@ -6574,7 +6574,7 @@ trap '_IgnoreKeypresses_ OFF ; exit 0' EXIT INT QUIT ABRT TERM then if [ $# -lt 2 ] || [ -z "$2" ]; then screen -dmS "rtrmon" $APPPATH -monitor - elif [ "$2" -ge 1 ] && [ "$2" -le 6 ]; then + elif [ "$2" -ge 1 ] && [ "$2" -le 7 ]; then screen -dmS "rtrmon" $APPPATH -monitor $2 else screen -dmS "rtrmon" $APPPATH -monitor @@ -6591,7 +6591,7 @@ trap '_IgnoreKeypresses_ OFF ; exit 0' EXIT INT QUIT ABRT TERM echo "" if [ $# -lt 2 ] || [ -z "$2" ]; then screen -dmS "rtrmon" $APPPATH -monitor - elif [ "$2" -ge 1 ] && [ "$2" -le 6 ]; then + elif [ "$2" -ge 1 ] && [ "$2" -le 7 ]; then screen -dmS "rtrmon" $APPPATH -monitor $2 else screen -dmS "rtrmon" $APPPATH -monitor From fce40f1e3f534dc17c0a4071ea76e6e8ed388790 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Sat, 10 Jan 2026 09:22:05 -0500 Subject: [PATCH 58/62] Update version to 2.3.0 and adjust beta flag Release 2.3.0 --- rtrmon.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rtrmon.sh b/rtrmon.sh index 76a43f6..ae1fd4a 100644 --- a/rtrmon.sh +++ b/rtrmon.sh @@ -24,8 +24,8 @@ export PATH="/sbin:/bin:/usr/sbin:/usr/bin:$PATH" # ------------------------------------------------------------------------------------------------------------------------- # System Variables (Do not change beyond this point or this may change the programs ability to function correctly) # ------------------------------------------------------------------------------------------------------------------------- -Version="2.3.0b7" -Beta=1 +Version="2.3.0" +Beta=0 ScreenshotMode=0 LOGFILE="/jffs/addons/rtrmon.d/rtrmon.log" # Logfile path/name that captures important date/time events - change APPPATH="/jffs/scripts/rtrmon.sh" # Path to the location of rtrmon.sh @@ -721,7 +721,7 @@ updatecheck () { elif [ "$DLVersion" != "$Version" ]; then DLVersionPF=$(printf "%-8s" $DLVersion) VersionPF=$(printf "%-8s" $Version) - UpdateNotify="${InvYellow} ${InvDkGray}${CWhite} Update available: v$VersionPF -> v$DLVersionPF ${CClear}" + UpdateNotify="${InvYellow} ${InvDkGray}${CWhite} Update available: v$VersionPF -> v$DLVersionPF ${CClear}" echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) RTRMON[$$] - INFO: A new update (v$DLVersion) is available to download" >> $LOGFILE else UpdateNotify=0 @@ -6591,7 +6591,7 @@ trap '_IgnoreKeypresses_ OFF ; exit 0' EXIT INT QUIT ABRT TERM echo "" if [ $# -lt 2 ] || [ -z "$2" ]; then screen -dmS "rtrmon" $APPPATH -monitor - elif [ "$2" -ge 1 ] && [ "$2" -le 7 ]; then + elif [ "$2" -ge 1 ] && [ "$2" -le 6 ]; then screen -dmS "rtrmon" $APPPATH -monitor $2 else screen -dmS "rtrmon" $APPPATH -monitor From 1a58756d4b1f28ed2f6425a68a7f998b4003010d Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Sat, 10 Jan 2026 09:22:28 -0500 Subject: [PATCH 59/62] Update version and last updated date in README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 33551f9..907e676 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# RTRMON v2.3.0b7 +# RTRMON v2.3.0b Asus-Merlin Router Monitor by Viktor Jaep, 2022-2026 -Updated on 2026-Jan-7 +Updated on 2026-Jan-10 --- From 1d008e4b8c60bf99f6ce12fd99fc7d5143e521eb Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Sat, 10 Jan 2026 09:22:37 -0500 Subject: [PATCH 60/62] Update version number to v2.3.0 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 907e676..45ef1f9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# RTRMON v2.3.0b +# RTRMON v2.3.0 Asus-Merlin Router Monitor by Viktor Jaep, 2022-2026 Updated on 2026-Jan-10 From cfc479a95c9f58ebb0f19895930a17ec563b0a20 Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Sat, 10 Jan 2026 09:23:08 -0500 Subject: [PATCH 61/62] Rename netmon-poc.sh to archive/netmon-poc.sh --- netmon-poc.sh => archive/netmon-poc.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename netmon-poc.sh => archive/netmon-poc.sh (100%) diff --git a/netmon-poc.sh b/archive/netmon-poc.sh similarity index 100% rename from netmon-poc.sh rename to archive/netmon-poc.sh From 9e5fa993bdbbb3d151a7e7d38413c996791b42ca Mon Sep 17 00:00:00 2001 From: ViktorJp <97465574+ViktorJp@users.noreply.github.com> Date: Sat, 10 Jan 2026 09:23:36 -0500 Subject: [PATCH 62/62] Update changelog for v2.3.0 release Updated version number and added release date for v2.3.0. --- changelog.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index 60a50d3..6876cd2 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,4 +1,4 @@ -v2.3.0b7 - (TBA) +v2.3.0 - (January 10, 2026) - PATCH: HUGE HUGE THANKS to both @ExtremeFiretop and @visortgw for their help getting the wired/wireless client page (#7) working again. Apparently something had broken between a firmware release that seemed to be causing some incorrect reporting on this page. Both these