What's new

ASUS BT10 - Knowing what's connected via SSH

Longtrail

New Around Here
Hi Folks,

It's my first post and I'm definitely a newbie as I read many threads and scratch my head so please be patient!... There's a lot I don't understand!

I'm slightly OCD and like to make sure that anything connected to my main network (not Guest or IOT) is known to me and is a recognized device. To do this I manually assign IP addresses in the Advanced Settings -> Lan -> DHCP Server page. I then reserve certain ip ranges for computers, phones, tablets. etc. I still allow connections but have the starting ip as 192.168.10.150, anything that connects and is above 150 then sets my alarm bells ringing!

We have a number of devices especially Apple products where I turn "Private W-Fi Address" off so that the registered mac address is used to assign an ip address within the given IP address range.

I have kids and so they often like to mess around with settings to try and get around parental controls, etc. and so I find things on the network that have ip addresses in the 192.168.10.150 to 192.168.10.255 range. I will often fix the devices but often times notice that the connected devices on the router admin page or through the web app are really out of date and I've really lost trust in the ways to display connected devices (there seem to be a few ways to display connected devices).

I have granted myself ssh access to the main router (I have two additional nodes) and I'm trying to find a good way to see what the connected devices are, I've been working on a shell script to do this (with mixed results) and so I'm wondering if anyone has tackled this problem with a similar approach? Based on my research /tmp/clientlist.json may contain the data I'm after but my results are still not quite there yet. Here's the script:

Code:
#!/bin/sh

JSON_FILE="/tmp/clientlist.json"

echo "IP Address        MAC Address          Node               Band"
echo "------------------------------------------------------------------"

jq -r '
  to_entries[] |               # each NODE_MAC
  .key as $node_mac |
  .value | to_entries[] |       # each BAND
  .key as $band |
  .value | to_entries[] |       # each CLIENT_MAC
  [.value.ip, .key, $node_mac, $band] |
  @tsv
' "$JSON_FILE" | sort -t. -k1,1n -k2,2n -k3,3n -k4,4n |
awk -F'\t' '{printf "%-16s %-20s %-18s %s\n", ($1==""?"-":$1),$2,$3,$4}'

I'm curious if anyone else has solved this issue? I've read some other posts but they seem to download other software and given I don't have Merlin I'm wondering if I can put something together... I get a response from my script but there are some entries where the ip address is not given.
 
ssh access will show in the logs. This is me starting and ending an ssh session.
Code:
Jan 20 06:55:25 ripshod dropbear[14700]: Child connection from 10.0.0.3:47080
Jan 20 06:55:25 ripshod dropbear[14700]: Password auth succeeded for 'Gilly' from 10.0.0.3:47080
Jan 20 06:56:20 ripshod dropbear[14700]: Exit (Gilly) from <10.0.0.3:47080>: Error reading: Connection reset by peer
So if you filter the log for "dropbear" you'll acheive what you want. The ip can be checked against the mac in the client list, but these days that's unreliable
 
ssh access will show in the logs

The OP likes to log the clients connected to WLAN though, not the clients accessing SSH. I see older threads around SNB Forums mostly focusing on home automation, but I don't know what works in stock Asuswrt.
 
I had occasion to make some crude ones for both Merlin FW (Main and Nodes) and Stock Nodes when I was trialling my IoT Device fixes here.
  • The Merlin one uses (but you can easily make your own) DHCP_clients.csv
  • The stock one embeds the same list in the file as uploading it to /tmp/ is not preserved on reboots etc. You just SSH to the stock node (or Main) and copy paste it, hit enter,
Code:
#!/bin/sh
# RSSI Monitor for Merlin Firmware (Main Router or Node)
# Shows: Name, MAC, IP Address, RSSI
# Gets names from nvram first, falls back to /jffs/scripts/DHCP_clients.csv
# Gets IPs from ARP first, falls back to /jffs/scripts/DHCP_clients.csv
# Requires: /jffs/scripts/DHCP_clients.csv (exported from YazDHCP)

DHCP_USED=0

echo "=== 2.4GHz CLIENTS ==="
for i in wl0.1 wl0.2 wl0.3; do
  for MAC in $(wl -i $i assoclist 2>/dev/null | awk '{print $2}'); do
    if [ -n "$MAC" ]; then
      RSSI=$(wl -i $i rssi $MAC 2>/dev/null)
  
      # Try nvram first, then fall back to DHCP_clients.csv
      NAME=$(nvram get custom_clientlist | grep -o "[^<>]*>$MAC" | cut -d'>' -f1)
      if [ -z "$NAME" ] && [ -f /jffs/scripts/DHCP_clients.csv ]; then
        NAME=$(grep -i "$MAC" /jffs/scripts/DHCP_clients.csv | cut -d',' -f3)
      fi
      [ -z "$NAME" ] && NAME="Unknown"
  
      # Try ARP first, then fall back to DHCP_clients.csv
      IP=$(arp -a | grep -i "$MAC" | awk '{print $2}' | tr -d '()')
      IP_SOURCE=""
      if [ -z "$IP" ] && [ -f /jffs/scripts/DHCP_clients.csv ]; then
        IP=$(grep -i "$MAC" /jffs/scripts/DHCP_clients.csv | cut -d',' -f2)
        if [ -n "$IP" ]; then
          IP_SOURCE="*"
          DHCP_USED=1
        fi
      fi
      [ -z "$IP" ] && IP="No-IP"
  
      echo "$NAME [$MAC] ($IP$IP_SOURCE): $RSSI dBm"
    fi
  done
done | sort

echo ""
echo "=== 5GHz CLIENTS ==="
for i in wl1.1 wl1.2 wl1.3; do
  for MAC in $(wl -i $i assoclist 2>/dev/null | awk '{print $2}'); do
    if [ -n "$MAC" ]; then
      RSSI=$(wl -i $i rssi $MAC 2>/dev/null)
  
      # Try nvram first, then fall back to DHCP_clients.csv
      NAME=$(nvram get custom_clientlist | grep -o "[^<>]*>$MAC" | cut -d'>' -f1)
      if [ -z "$NAME" ] && [ -f /jffs/scripts/DHCP_clients.csv ]; then
        NAME=$(grep -i "$MAC" /jffs/scripts/DHCP_clients.csv | cut -d',' -f3)
      fi
      [ -z "$NAME" ] && NAME="Unknown"
  
      # Try ARP first, then fall back to DHCP_clients.csv
      IP=$(arp -a | grep -i "$MAC" | awk '{print $2}' | tr -d '()')
      IP_SOURCE=""
      if [ -z "$IP" ] && [ -f /jffs/scripts/DHCP_clients.csv ]; then
        IP=$(grep -i "$MAC" /jffs/scripts/DHCP_clients.csv | cut -d',' -f2)
        if [ -n "$IP" ]; then
          IP_SOURCE="*"
          DHCP_USED=1
        fi
      fi
      [ -z "$IP" ] && IP="No-IP"
  
      echo "$NAME [$MAC] ($IP$IP_SOURCE): $RSSI dBm"
    fi
  done
done | sort

if [ $DHCP_USED -eq 1 ]; then
  echo ""
  echo "* IP extracted from DHCP Client List"
fi

The DHCP_clients.csv format when opened as a txt file is:

MAC,IP,HOSTNAME,DNS
B0:81:84:E1:0A:88,192.168.63.165,ShellyAnnexTRVGW,
B0:81:84:E2:65:E4,192.168.63.166,ShellySpr1TRVGW,
B0:81:84:E2:69:1C,192.168.63.167,ShellySpr2TRVGW,
B0:81:84:E1:0B:0C,192.168.63.168,ShellySpr3TRVGW,
C4:E7:AE:09:08:49,192.168.63.169,MerossThermostat,

In Excel it is just the four fields.

Optional: Add this line to profile.add in /jffs/configs/ to run from anywhere (without having to cd /jffs/scripts/ and issuing sh show_rssi_merlin.sh)

Code:
alias show_rssi_merlin="sh /jffs/scripts/show_rssi_merlin.sh" # List RSSI of both bands on Router (needs DHCP_clients.csv)
 
Last edited:
This is the Stock one. I cannot get Name or IP from Stock Nodes that are NOT embedded in the DHCP List (5 example lines shown below for format).

Code:
sh << 'EOF'
#!/bin/sh
# RSSI Monitor for Stock Firmware (Main Router or Node)
# Shows: Name, MAC, IP Address, RSSI
# DHCP client data embedded in script - no external files needed

# Embedded DHCP client list (MAC,IP,HOSTNAME)
get_dhcp_name() {
  MAC_UPPER=$(echo "$1" | tr '[:lower:]' '[:upper:]')
  case "$MAC_UPPER" in
    B0:81:84:E1:0A:88) echo "ShellyAnnexTRVGW" ;;
    B0:81:84:E2:65:E4) echo "ShellySpr1TRVGW" ;;
    B0:81:84:E2:69:1C) echo "ShellySpr2TRVGW" ;;
    B0:81:84:E1:0B:0C) echo "ShellySpr3TRVGW" ;;
    C4:E7:AE:09:08:49) echo "MerossThermostat" ;;
    *) echo "" ;;
  esac
}

get_dhcp_ip() {
  MAC_UPPER=$(echo "$1" | tr '[:lower:]' '[:upper:]')
  case "$MAC_UPPER" in
    B0:81:84:E1:0A:88) echo "192.168.63.165" ;;
    B0:81:84:E2:65:E4) echo "192.168.63.166" ;;
    B0:81:84:E2:69:1C) echo "192.168.63.167" ;;
    B0:81:84:E1:0B:0C) echo "192.168.63.168" ;;
    C4:E7:AE:09:08:49) echo "192.168.63.169" ;;
    *) echo "" ;;
  esac
}

OUTPUT_24=""
OUTPUT_5=""

for i in wl0.1 wl0.2 wl0.3; do
  for MAC in $(wl -i $i assoclist 2>/dev/null | awk '{print $2}'); do
    if [ -n "$MAC" ]; then
      RSSI=$(wl -i $i rssi $MAC 2>/dev/null)
   
      # Try nvram first, then embedded DHCP data
      NAME=$(nvram get custom_clientlist | grep -o "[^<>]*>$MAC" | cut -d'>' -f1)
      if [ -z "$NAME" ]; then
        NAME=$(get_dhcp_name "$MAC")
      fi
      [ -z "$NAME" ] && NAME="Unknown"
   
      # Try ARP first, then embedded DHCP data
      IP=$(arp -a | grep -i "$MAC" | awk '{print $2}' | tr -d '()')
      IP_SOURCE=""
      if [ -z "$IP" ]; then
        IP=$(get_dhcp_ip "$MAC")
        [ -n "$IP" ] && IP_SOURCE="*"
      fi
      [ -z "$IP" ] && IP="No-IP"
   
      OUTPUT_24="$OUTPUT_24$NAME [$MAC] ($IP$IP_SOURCE): $RSSI dBm
"
    fi
  done
done

for i in wl1.1 wl1.2 wl1.3; do
  for MAC in $(wl -i $i assoclist 2>/dev/null | awk '{print $2}'); do
    if [ -n "$MAC" ]; then
      RSSI=$(wl -i $i rssi $MAC 2>/dev/null)
   
      # Try nvram first, then embedded DHCP data
      NAME=$(nvram get custom_clientlist | grep -o "[^<>]*>$MAC" | cut -d'>' -f1)
      if [ -z "$NAME" ]; then
        NAME=$(get_dhcp_name "$MAC")
      fi
      [ -z "$NAME" ] && NAME="Unknown"
   
      # Try ARP first, then embedded DHCP data
      IP=$(arp -a | grep -i "$MAC" | awk '{print $2}' | tr -d '()')
      IP_SOURCE=""
      if [ -z "$IP" ]; then
        IP=$(get_dhcp_ip "$MAC")
        [ -n "$IP" ] && IP_SOURCE="*"
      fi
      [ -z "$IP" ] && IP="No-IP"
   
      OUTPUT_5="$OUTPUT_5$NAME [$MAC] ($IP$IP_SOURCE): $RSSI dBm
"
    fi
  done
done

echo "=== 2.4GHz CLIENTS ==="
echo "$OUTPUT_24" | sort

echo ""
echo "=== 5GHz CLIENTS ==="
echo "$OUTPUT_5" | sort

# Check if any IPs were from DHCP list
if echo "$OUTPUT_24$OUTPUT_5" | grep -q '\*'; then
  echo ""
  echo "* IP extracted from DHCP Client List"
fi
EOF
 
Last edited:
Thank you so much jksmurf - I really appreciate the response and help. I ran the two different scripts and get similar output from both; I'll need to look at the code and digest it! It's not showing anything connected to the 2.4GHz network and 9 entries on the 5GHz network, there's currently about 50 devices connected so I'm missing a bunch of info! This is all new to me so the learning curve at the moment is steep. I'm good on the OS side (bash, Linux/Unix, ...) but not the networking side so don't know what the commands are or files I should investigate yet...

When I've got this fully functioning I plan to invoke the script with something like this:

ssh [email protected] 'sh /tmp/home/root/snb2.sh'

This way I just get the list returned to me without ever having to logon (other than providing the admin password which can also be negated with ssh keys). I'll then set this up with an alias so something like this:

alias kids="ssh [email protected] 'sh /tmp/home/root/snb2.sh'"
 
I'll need to look at the code and digest it!
Honestly, I threw it together using vibe coding, I needed a tool to give me RSSI to troubleshoot an IoT network. It’s probably terrible, I intentionally used the word crude as that’s how folks who can actually code probably view it.

Like you I’m a bit OCD on having things line up. You may be missing devices as you will need to check if wl0.1 wl0.2 wl0.3 etc are correct for your network.
 
What is RSSI - is it the power/strength of a signal? Why is it of interest?

No problem with crude code, it can be refined and sometimes if it just does the job then that's good enough, it's not like it's commercial software!

How do I figure out the wl0.*'s and the wl1.*'s etc. As you can see I'm a newbie, I have so many other questions but tend to tackle things bit by bit! Thanks.
 
What is RSSI - is it the power/strength of a signal?
Pretty much. These are at the router. The IoT devices I have (Shelly’s) have one on (at) the device.
Why is it of interest?
In a multi-node mesh system, you prefer the devices to latch on to and stay latched on to the node with the best signal and get kicked off weak signals which it might work on, but slowly or poorly.

The in device RSSI threshold (Shelly’s have this) can affect this, and on the router, roaming assist (if enabled) can affect it and so can Smart Connects Steering Trigger and STA, with the latter two more about moving between 2.4Ghz and 5Ghz bands, if you have just two.
No problem with crude code, it can be refined and sometimes if it just does the job then that's good enough, it's not like it's commercial software!

How do I figure out the wl0.*'s and the wl1.*'s etc. As you can see I'm a newbie, I have so many other questions but tend to tackle things bit by bit! Thanks.
Try this.

Step 1: Find how many radios you have:

Code:
nvram show | grep -E "^wl[0-9]_ifname"

Step 2: For Guest Network Pro monitoring, append .1 to each wl number you see:
  • If you see wl0 and wl1 (like on my GT-AX6000) → use wl0.1 and wl1.1 in the scripts
  • If you see wl0, wl1, and wl2 (tri-band router) → use wl0.1, wl1.1, and wl2.1 in the scripts
The .1 represents your first guest network (Guest Network Pro), which is where my IoT (mainly Shelly devices) connect on each radio band.

I got the above from the same source as my vibe coder, so I take no credit and if it’s incorrect, hopefully someone who’s not a hack like me will correct it.

====================== Addendum =======================

The command

Code:
nvram show | grep -E "^wl[0-9]_ifname"

shows the main/primary radios, not Guest Network Pro.

The output you see, e.g.
  • wl0_ifname=eth6 ← This is your main 2.4GHz radio
  • wl1_ifname=eth7 ← This is your main 5GHz radio
For Guest Network Pro, you need the .1 suffix, incremented by .1 for each network.

So to clarify the full picture:

Main network interfaces:
  • wl0 (or eth6) = Primary 2.4GHz
  • wl1 (or eth7) = Primary 5GHz
Guest Network 1:
  • wl0.1 (2.4GHz)
  • wl1.1 (5GHz)
Guest Network 2:
  • wl0.2 (2.4GHz)
  • wl1.2 (5GHz)
That's 6 interfaces total per node.

Note that the scripts reference wl1.3 (or wl0.3), but there's no third guest network to check, yet. But if I add one, it will be used!

The RSSI monitoring scripts above use ONLY wl0.x and wl1.x because I just wanted to see Guest Devices, not the main network.

If you wanted to monitor RSSI for devices on your main network, you'd use wl0 and wl1 instead, or as well.
 
Last edited:
Ok, for completeness:

For Merlin FW Routers, two Guest Networks, my filename is show_rssi_merlin.sh

Code:
#!/bin/sh
# ============================================================================
# UNIFIED RSSI Monitor for ALL Merlin Routers (Main + Nodes)
# ============================================================================
# Works on: GT-AX6000 Main + RT-AX58U Kitchen Node
# Shows: Device Name, MAC Address, IP Address, RSSI
# Names: Tries nvram custom_clientlist first, falls back to DHCP_clients.csv
# IPs: Tries ARP first, falls back to DHCP_clients.csv
# Requires: /jffs/scripts/DHCP_clients.csv (YazDHCP export)
# CSV Format: ClientName,IPAddress,MACAddress
# ============================================================================

echo ""
echo "=== 2.4GHz MAIN NETWORK CLIENTS (wl0) ==="
for MAC in $(wl -i wl0 assoclist 2>/dev/null | awk '{print $2}'); do 
  if [ -n "$MAC" ]; then
    RSSI=$(wl -i wl0 rssi $MAC 2>/dev/null)
    
    # Get name - try nvram first, fall back to CSV
    NAME=$(nvram get custom_clientlist 2>/dev/null | grep -o "[^<>]*>$MAC" | cut -d'>' -f1)
    if [ -z "$NAME" ] && [ -f /jffs/scripts/DHCP_clients.csv ]; then
      NAME=$(grep -i "$MAC" /jffs/scripts/DHCP_clients.csv | cut -d',' -f3)
    fi
    [ -z "$NAME" ] && NAME="Unknown"
    
    # Get IP - try ARP first, fall back to CSV
    IP=$(arp -a | grep -i "$MAC" | awk '{print $2}' | tr -d '()')
    if [ -z "$IP" ] && [ -f /jffs/scripts/DHCP_clients.csv ]; then
      IP=$(grep -i "$MAC" /jffs/scripts/DHCP_clients.csv | cut -d',' -f2)
    fi
    [ -z "$IP" ] && IP="No-IP"
    
    echo "$NAME [$MAC] ($IP): $RSSI dBm"
  fi
done | sort

echo ""
echo "=== 2.4GHz GUEST/IOT NETWORK CLIENTS (wl0.1/wl0.2) ==="
for i in wl0.1 wl0.2; do
  for MAC in $(wl -i $i assoclist 2>/dev/null | awk '{print $2}'); do 
    if [ -n "$MAC" ]; then
      RSSI=$(wl -i $i rssi $MAC 2>/dev/null)
      
      NAME=$(nvram get custom_clientlist 2>/dev/null | grep -o "[^<>]*>$MAC" | cut -d'>' -f1)
      if [ -z "$NAME" ] && [ -f /jffs/scripts/DHCP_clients.csv ]; then
        NAME=$(grep -i "$MAC" /jffs/scripts/DHCP_clients.csv | cut -d',' -f3)
      fi
      [ -z "$NAME" ] && NAME="Unknown"
      
      IP=$(arp -a | grep -i "$MAC" | awk '{print $2}' | tr -d '()')
      if [ -z "$IP" ] && [ -f /jffs/scripts/DHCP_clients.csv ]; then
        IP=$(grep -i "$MAC" /jffs/scripts/DHCP_clients.csv | cut -d',' -f2)
      fi
      [ -z "$IP" ] && IP="No-IP"
      
      echo "$NAME [$MAC] ($IP): $RSSI dBm"
    fi
  done
done | sort

echo ""
echo "=== 5GHz MAIN NETWORK CLIENTS (wl1) ==="
for MAC in $(wl -i wl1 assoclist 2>/dev/null | awk '{print $2}'); do 
  if [ -n "$MAC" ]; then
    RSSI=$(wl -i wl1 rssi $MAC 2>/dev/null)
    
    NAME=$(nvram get custom_clientlist 2>/dev/null | grep -o "[^<>]*>$MAC" | cut -d'>' -f1)
    if [ -z "$NAME" ] && [ -f /jffs/scripts/DHCP_clients.csv ]; then
      NAME=$(grep -i "$MAC" /jffs/scripts/DHCP_clients.csv | cut -d',' -f3)
    fi
    [ -z "$NAME" ] && NAME="Unknown"
    
    IP=$(arp -a | grep -i "$MAC" | awk '{print $2}' | tr -d '()')
    if [ -z "$IP" ] && [ -f /jffs/scripts/DHCP_clients.csv ]; then
      IP=$(grep -i "$MAC" /jffs/scripts/DHCP_clients.csv | cut -d',' -f2)
    fi
    [ -z "$IP" ] && IP="No-IP"
    
    echo "$NAME [$MAC] ($IP): $RSSI dBm"
  fi
done | sort

echo ""
echo "=== 5GHz GUEST NETWORK CLIENTS (wl1.1/wl1.2) ==="
for i in wl1.1 wl1.2; do
  for MAC in $(wl -i $i assoclist 2>/dev/null | awk '{print $2}'); do 
    if [ -n "$MAC" ]; then
      RSSI=$(wl -i $i rssi $MAC 2>/dev/null)
      
      NAME=$(nvram get custom_clientlist 2>/dev/null | grep -o "[^<>]*>$MAC" | cut -d'>' -f1)
      if [ -z "$NAME" ] && [ -f /jffs/scripts/DHCP_clients.csv ]; then
        NAME=$(grep -i "$MAC" /jffs/scripts/DHCP_clients.csv | cut -d',' -f3)
      fi
      [ -z "$NAME" ] && NAME="Unknown"
      
      IP=$(arp -a | grep -i "$MAC" | awk '{print $2}' | tr -d '()')
      if [ -z "$IP" ] && [ -f /jffs/scripts/DHCP_clients.csv ]; then
        IP=$(grep -i "$MAC" /jffs/scripts/DHCP_clients.csv | cut -d',' -f2)
      fi
      [ -z "$IP" ] && IP="No-IP"
      
      echo "$NAME [$MAC] ($IP): $RSSI dBm"
    fi
  done
done | sort

echo ""
echo "To check node clients, SSH to each node:"
echo "  ssh [email protected]  # MB (Stock)"
echo "  ssh [email protected]  # Annex (Stock)"
echo "  ssh [email protected]  # Kitchen (Merlin)"
echo ""
 
Last edited:
And for Stock NODES (which has different interface naming apparently).
I call this one show_rssi_stock_node.txt

Will do one for Stock MAIN in the next post.


To check Stock firmware interface naming, first run this:

Code:
for i in wl0 wl0.1 wl0.2 wl0.3 wl1 wl1.1 wl1.2 wl1.3; do
  echo "=== Testing $i ==="
  wl -i $i assoclist 2>/dev/null
done

This will tell you:
  • Which interfaces exist and work
  • Which have connected devices
  • What the actual MACs are
Modify the Code below as necessary with your interfaces.
  • Also amend the known MAC/Devices lists. Without these it will show the device's MAC but "Unknown".
  • SSH in to the Node, copy/paste in the command window, you should see the devices on the Stock Node.
  • The second time (until a reboot) you can just type rssi.
TBH all this is easier in Merlin (see script above) and especially with @Viktor Jaep RTRMON Addon (see the Table in Screen 7 of the Addon).

Code:
cat > /tmp/rssi.sh << 'EOF'
get_dhcp_name() {
  MAC_UPPER=$(echo "$1" | tr '[:lower:]' '[:upper:]')
  case "$MAC_UPPER" in
    98:A1:4A:CD:6F:49) echo "BrevilleCoffeeMC" ;;
    B0:81:84:E3:91:00) echo "ShellyLvgRmTRVGW" ;;
    44:17:93:21:A6:2C) echo "ShellyCHManButton" ;;
    A0:A3:B3:67:C8:E0) echo "ShellyMainHWCTemp" ;;
    C8:2E:18:0B:92:0C) echo "CHUnderfloorTemp" ;;
    *) echo "" ;;
  esac
}

get_dhcp_ip() {
  MAC_UPPER=$(echo "$1" | tr '[:lower:]' '[:upper:]')
  case "$MAC_UPPER" in
    98:A1:4A:CD:6F:49) echo "192.168.63.39" ;;
    B0:81:84:E3:91:00) echo "192.168.63.163" ;;
    44:17:93:21:A6:2C) echo "192.168.63.126" ;;
    A0:A3:B3:67:C8:E0) echo "192.168.63.135" ;;
    C8:2E:18:0B:92:0C) echo "192.168.63.134" ;;
    *) echo "" ;;
  esac
}

echo ""
echo "=== 2.4GHz GUEST/IOT NETWORK CLIENTS (wl0.1/wl0.2/wl0.3) ==="
for i in wl0.1 wl0.2 wl0.3; do
  for MAC in $(wl -i $i assoclist 2>/dev/null | awk '{print $2}'); do 
    if [ -n "$MAC" ]; then
      RSSI=$(wl -i $i rssi $MAC 2>/dev/null)
      NAME=$(get_dhcp_name "$MAC")
      if [ -z "$NAME" ]; then
        NAME="Unknown"
        echo "$NAME [$MAC]: $RSSI dBm"
      else
        IP=$(arp -a | grep -i "$MAC" | awk '{print $2}' | tr -d '()')
        [ -z "$IP" ] && IP=$(get_dhcp_ip "$MAC")
        [ -z "$IP" ] && IP="No-IP"
        echo "$NAME [$MAC] ($IP): $RSSI dBm"
      fi
    fi
  done
done | sort

echo ""
echo "=== 5GHz GUEST NETWORK CLIENTS (wl1.1/wl1.2/wl1.3) ==="
for i in wl1.1 wl1.2 wl1.3; do
  for MAC in $(wl -i $i assoclist 2>/dev/null | awk '{print $2}'); do 
    if [ -n "$MAC" ]; then
      RSSI=$(wl -i $i rssi $MAC 2>/dev/null)
      NAME=$(get_dhcp_name "$MAC")
      if [ -z "$NAME" ]; then
        NAME="Unknown"
        echo "$NAME [$MAC]: $RSSI dBm"
      else
        IP=$(arp -a | grep -i "$MAC" | awk '{print $2}' | tr -d '()')
        [ -z "$IP" ] && IP=$(get_dhcp_ip "$MAC")
        [ -z "$IP" ] && IP="No-IP"
        echo "$NAME [$MAC] ($IP): $RSSI dBm"
      fi
    fi
  done
done | sort
EOF
sh /tmp/rssi.sh

# Create alias for easy re-running
alias rssi='sh /tmp/rssi.sh'
echo ""
echo "Alias created! You can now just type 'rssi' to run this script again."
echo ""
 
Last edited:
And this last one for Stock MAIN (show_rssi_stock_main.txt)

This one does NOT need modifying of the Tables with MAC/Device Names, it should get this from the Stock (Main) Router.
SSH to the Stock Main and Copy Paste, Enter.
I have no easy way to test this (all my Mains are Merlin based).

Note: If you run it on a Merlin Main with YazDHCP (mine) you may get some "No-IP" entries.
If so just ping known static IPs to populate the ARP Table i.e.
Code:
ping -c 1 192.168.63.131 >/dev/null 2>&1
and run rssi again.

Code:
cat > /tmp/rssi.sh << 'EOF'
# Function to get IP from DHCP lease files
get_lease_ip() {
  MAC_LOWER=$(echo "$1" | tr '[:upper:]' '[:lower:]')
  # Check each lease file directly
  IP=$(grep "$MAC_LOWER" /var/lib/misc/dnsmasq.leases 2>/dev/null | awk '{print $3}')
  [ -z "$IP" ] && IP=$(grep "$MAC_LOWER" /var/lib/misc/dnsmasq-1.leases 2>/dev/null | awk '{print $3}')
  [ -z "$IP" ] && IP=$(grep "$MAC_LOWER" /var/lib/misc/dnsmasq-2.leases 2>/dev/null | awk '{print $3}')
  echo "$IP"
}

echo ""
echo "=== 2.4GHz MAIN NETWORK CLIENTS (wl0) ==="
for MAC in $(wl -i wl0 assoclist 2>/dev/null | awk '{print $2}'); do 
  if [ -n "$MAC" ]; then
    RSSI=$(wl -i wl0 rssi $MAC 2>/dev/null)
    NAME=$(nvram get custom_clientlist | grep -o "[^<>]*>$MAC" | cut -d'>' -f1)
    [ -z "$NAME" ] && NAME="Unknown"
    
    # Try ARP first, then DHCP lease files
    IP=$(arp -a | grep -i "$MAC" | awk '{print $2}' | tr -d '()')
    IP_SOURCE=""
    if [ -z "$IP" ]; then
      IP=$(get_lease_ip "$MAC")
      [ -n "$IP" ] && IP_SOURCE="*"
    fi
    [ -z "$IP" ] && IP="No-IP"
    
    echo "$NAME [$MAC] ($IP$IP_SOURCE): $RSSI dBm"
  fi
done | sort

echo ""
echo "=== 2.4GHz GUEST/IOT NETWORK CLIENTS (wl0.1/wl0.2) ==="
for i in wl0.1 wl0.2; do
  for MAC in $(wl -i $i assoclist 2>/dev/null | awk '{print $2}'); do 
    if [ -n "$MAC" ]; then
      RSSI=$(wl -i $i rssi $MAC 2>/dev/null)
      NAME=$(nvram get custom_clientlist | grep -o "[^<>]*>$MAC" | cut -d'>' -f1)
      [ -z "$NAME" ] && NAME="Unknown"
      
      IP=$(arp -a | grep -i "$MAC" | awk '{print $2}' | tr -d '()')
      IP_SOURCE=""
      if [ -z "$IP" ]; then
        IP=$(get_lease_ip "$MAC")
        [ -n "$IP" ] && IP_SOURCE="*"
      fi
      [ -z "$IP" ] && IP="No-IP"
      
      echo "$NAME [$MAC] ($IP$IP_SOURCE): $RSSI dBm"
    fi
  done
done | sort

echo ""
echo "=== 5GHz MAIN NETWORK CLIENTS (wl1) ==="
for MAC in $(wl -i wl1 assoclist 2>/dev/null | awk '{print $2}'); do 
  if [ -n "$MAC" ]; then
    RSSI=$(wl -i wl1 rssi $MAC 2>/dev/null)
    NAME=$(nvram get custom_clientlist | grep -o "[^<>]*>$MAC" | cut -d'>' -f1)
    [ -z "$NAME" ] && NAME="Unknown"
    
    IP=$(arp -a | grep -i "$MAC" | awk '{print $2}' | tr -d '()')
    IP_SOURCE=""
    if [ -z "$IP" ]; then
      IP=$(get_lease_ip "$MAC")
      [ -n "$IP" ] && IP_SOURCE="*"
    fi
    [ -z "$IP" ] && IP="No-IP"
    
    echo "$NAME [$MAC] ($IP$IP_SOURCE): $RSSI dBm"
  fi
done | sort

echo ""
echo "=== 5GHz GUEST NETWORK CLIENTS (wl1.1/wl1.2) ==="
for i in wl1.1 wl1.2; do
  for MAC in $(wl -i $i assoclist 2>/dev/null | awk '{print $2}'); do 
    if [ -n "$MAC" ]; then
      RSSI=$(wl -i $i rssi $MAC 2>/dev/null)
      NAME=$(nvram get custom_clientlist | grep -o "[^<>]*>$MAC" | cut -d'>' -f1)
      [ -z "$NAME" ] && NAME="Unknown"
      
      IP=$(arp -a | grep -i "$MAC" | awk '{print $2}' | tr -d '()')
      IP_SOURCE=""
      if [ -z "$IP" ]; then
        IP=$(get_lease_ip "$MAC")
        [ -n "$IP" ] && IP_SOURCE="*"
      fi
      [ -z "$IP" ] && IP="No-IP"
      
      echo "$NAME [$MAC] ($IP$IP_SOURCE): $RSSI dBm"
    fi
  done
done | sort
EOF
sh /tmp/rssi.sh

# Create alias for easy re-running
alias rssi='sh /tmp/rssi.sh'
echo ""
echo "Alias created! You can now just type 'rssi' to run this script again."
echo ""
 
Last edited:
I need some time to digest all of this so apologies for the lack of response, I've really grateful for your help. Thank you.
No worries, you have kids, they should always get first priority, they don’t stay kids for long.

In the first instance rather than work out which interfaces you have (one of my first notes above) I’d just try to copy/paste the more recent stock main script on to the main router and see what you get.

I’ve expanded these scripts to all networks now, it was just Guest/IoT before, which was the script you ran initially and saw there were devices missing (the reason for which is self-explanatory).

Then do the same for the nodes. IIRC you don’t run Merlin so copy paste the stock scripts in their entirety. The node one will need your own device list embedded in it for Device Name, otherwise it will just show as Unknown. You might find a better way to mine these details, so maybe you can improve upon them (you couldn’t make them worse!).

Anyway take your time, all good.
 

Latest threads

Support SNBForums w/ Amazon

If you'd like to support SNBForums, just use this link and buy anything on Amazon. Thanks!

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Back
Top