Dumb AP - Associated Stations Resolver

I can't make the script work. /etc/hosts is properly populated, but running the script in the command line returns sh: find: unknown operand and /etc/ethers becomes:

arp-scan Usage:
 
hosts Target
in given,
--localnet the
network the
 
will You
because arp-scan,
root require
 
target The
the specify
the in
(e.g. IPstart-IPend
range, inclusive
all specify
 
different These
line, command
 
"arp-scan use
 
bugs Report
the See
root@EAP615-3:~# cat /tmp/etc/ethers 
arp-scan Usage:
 
hosts Target
in given,
--localnet the
network the
 
will You
because arp-scan,
root require
 
target The
the specify
the in
(e.g. IPstart-IPend
range, inclusive
all specify
 
different These
line, command
 
"arp-scan use
 
bugs Report
the See

I have arp-scan installed. The script creates the symlinks.

Change if [ $FQDN != "find" ]; then
to
if [ "$FQDN" != "find" ]; then

If it will not help, run the script as sh -x scriptname and post the output.

It didn't help, so here's the output. Adding br-lan 10.0.0.0/24 manually to the arp-scan line did help though.

root@EAP615-3:~# sh -x /root/stationinfo.sh 
+ '[' '!' -e /tmp/etc/ethers ]
+ '[' '!' -e /tmp/etc/hosts ]
+ readlink -f /root/stationinfo.sh
+ cat
+ ifstatus lan
+ LANST='{
	"up": true,
	"pending": false,
	"available": true,
	"autostart": true,
	"dynamic": false,
	"uptime": 2758,
	"l3_device": "br-lan",
	"proto": "dhcp",
	"device": "br-lan",
	"metric": 0,
	"dns_metric": 0,
	"delegation": false,
	"ipv4-address": [
		{
			"address": "10.0.0.4",
			"mask": 24
		}
	],
	"ipv6-address": [
		
	],
	"ipv6-prefix": [
		
	],
	"ipv6-prefix-assignment": [
		
	],
	"route": [
		{
			"target": "0.0.0.0",
			"mask": 0,
			"nexthop": "10.0.0.1",
			"source": "10.0.0.4/32"
		}
	],
	"dns-server": [
		"10.0.0.1"
	],
	"dns-search": [
		"local"
	],
	"neighbors": [
		
	],
	"inactive": {
		"ipv4-address": [
			
		],
		"ipv6-address": [
			
		],
		"route": [
			
		],
		"dns-server": [
			
		],
		"dns-search": [
			
		],
		"neighbors": [
			
		]
	},
	"data": {
		"dhcpserver": "10.0.0.1",
		"hostname": "EAP615-3",
		"leasetime": 180,
		"ntpserver": "10.0.0.100"
	}
}'
+ echo+ jsonfilter '{
	"up": true,
	"pending": false,
	"available": true,
	"autostart": true,
	"dynamic": false,
	"uptime": 2758,
	"l3_device": "br-lan",
	"proto": "dhcp",
	"device": "br-lan",
	"metric": 0,
	"dns_metric": 0,
	"delegation": false,
	"ipv4-address": [
		{
			"address": "10.0.0.4",
			"mask": 24
		}
	],
	"ipv6-address": [
		
	],
	"ipv6-prefix": [
		
	],
	"ipv6-prefix-assignment": [
		
	],
	"route": [
		{
			"target": "0.0.0.0",
			"mask": 0,
			"nexthop": "10.0.0.1",
			"source": "10.0.0.4/32"
		}
	],
	"dns-server": [
		"10.0.0.1"
	],
	"dns-search": [
		"local"
	],
	"neighbors": [
		
	],
	"inactive": {
		"ipv4-address": [
			
		],
		"ipv6-address": [
			
		],
		"route": [
			
		],
		"dns-server": [
			
		],
		"dns-search": [
			
		],
		"neighbors": [
			
		]
	},
	"data": {
		"dhcpserver": "10.0.0.1",
		"hostname": "EAP615-3",
		"leasetime": 180,
		"ntpserver": "10.0.0.100"
	}
}'
 -e '@["ipv4-address"][0].address'
+ LANADDR=10.0.0.4
+ echo '{
	"up": true,
	"pending": false,
	"available": true,
	"autostart": true,
	"dynamic": false,
	"uptime": 2758,
	"l3_device": "br-lan",
	"proto": "dhcp",
	"device": "br-lan",
	"metric": 0,
	"dns_metric": 0,
	"delegation": false,
	"ipv4-address": [
		{
			"address": "10.0.0.4",
			"mask": 24
		}
	],
	"ipv6-address": [
		
	],
	"ipv6-prefix": [
		
	],
	"ipv6-prefix-assignment": [
		
	],
	"route": [
		{
			"target": "0.0.0.0",
			"mask": 0,
			"nexthop": "10.0.0.1",
			"source": "10.0.0.4/32"
		}
	],
	"dns-server": [
		"10.0.0.1"
	],
	"dns-search": [
		"local"
	],
	"neighbors": [
		
	],
	"inactive": {
		"ipv4-address": [
			
		],
		"ipv6-address": [
			
		],
		"route": [
			
		],
		"dns-server": [
			
		],
		"dns-search": [
			
		],
		"neighbors": [
			
		]
	},
	"data": {
		"dhcpserver": "10.0.0.1",
		"hostname": "EAP615-3",
		"leasetime": 180,
		"ntpserver": "10.0.0.100"
	}
}'
+ jsonfilter -e @.device
+ INTERFACE=br-lan
+ ip r
+ grep 'link\s\+ src '
+ awk -F ' ' '{print $1}'
+ LANNET=
+ echo '{
	"up": true,
	"pending": false,
	"available": true,
	"autostart": true,
	"dynamic": false,
	"uptime": 2758,
	"l3_device": "br-lan",
	"proto": "dhcp",
	"device": "br-lan",
	"metric": 0,
	"dns_metric": 0,
	"delegation": false,
	"ipv4-address": [
		{
			"address": "10.0.0.4",
			"mask": 24
		}
	],
	"ipv6-address": [
		
	],
	"ipv6-prefix": [
		
	],
	"ipv6-prefix-assignment": [
		
	],
	"route": [
		{
			"target": "0.0.0.0",
			"mask": 0,
			"nexthop": "10.0.0.1",
			"source": "10.0.0.4/32"
		}
	],
	"dns-server": [
		"10.0.0.1"
	],
	"dns-search": [
		"local"
	],
	"neighbors": [
		
	],
	"inactive": {
		"ipv4-address": [
			
		],
		"ipv6-address": [
			
		],
		"route": [
			
		],
		"dns-server": [
			
		],
		"dns-search": [
			
		],
		"neighbors": [
			
		]
	},
	"data": {
		"dhcpserver": "10.0.0.1",
		"hostname": "EAP615-3",
		"leasetime": 180,
		"ntpserver": "10.0.0.100"
	}
}'
+ jsonfilter -e '@["dns-server"][0]'
+ DNSSERVER=10.0.0.1
+ arp-scan -q -x -I br-lan
+ awk '-F ' '{print $2 " " $1}'
+ cat /etc/ethers
+ awk '-F ' '{print $2}'
+ nslookup Usage: 10.0.0.1
+ grep -m 1 arpa
+ awk '-F ' '{print $4}'
+ FQDN=
+ '['  '!=' find ]
+ echo 'Usage:	'
+ nslookup Target 10.0.0.1
+ grep -m 1 arpa
+ awk '-F ' '{print $4}'
+ FQDN=
+ '['  '!=' find ]
+ echo 'Target	'
+ nslookup given, 10.0.0.1
+ grep -m 1 arpa
+ awk '-F ' '{print $4}'
+ FQDN=
+ '['  '!=' find ]
+ echo 'given,	'
+ nslookup the 10.0.0.1
+ grep -m 1 arpa
+ awk '-F ' '{print $4}'
+ FQDN=
+ '['  '!=' find ]
+ echo 'the	'
+ nslookup the 10.0.0.1
+ grep -m 1 arpa
+ awk '-F ' '{print $4}'
+ FQDN=
+ '['  '!=' find ]
+ echo 'the	'
+ nslookup You 10.0.0.1
+ grep -m 1 arpa
+ awk '-F ' '{print $4}'
+ FQDN=
+ '['  '!=' find ]
+ echo 'You	'
+ nslookup arp-scan, 10.0.0.1
+ grep+  -m 1awk '-F ' '{print $4}'
 arpa
+ FQDN=
+ '['  '!=' find ]
+ echo 'arp-scan,	'
+ nslookup require 10.0.0.1
+ grep+ awk '-F ' '{print $4}'
 -m 1 arpa
+ FQDN=
+ '['  '!=' find ]
+ echo 'require	'
+ nslookup The 10.0.0.1
+ grep -m 1 arpa
+ awk '-F ' '{print $4}'
+ FQDN=
+ '['  '!=' find ]
+ echo 'The	'
+ nslookup specify 10.0.0.1
+ grep -m 1 arpa
+ awk '-F ' '{print $4}'
+ FQDN=
+ '['  '!=' find ]
+ echo 'specify	'
+ nslookup 'in' 10.0.0.1
+ grep -m 1 arpa
+ awk '-F ' '{print $4}'
+ FQDN=
+ '['  '!=' find ]
+ echo 'in	'
+ nslookup IPstart-IPend 10.0.0.1
+ grep -m 1 arpa
+ awk '-F ' '{print $4}'
+ FQDN=
+ '['  '!=' find ]
+ echo 'IPstart-IPend	'
+ nslookup inclusive 10.0.0.1
+ grep -m 1 arpa
+ awk '-F ' '{print $4}'
+ FQDN=
+ '['  '!=' find ]
+ echo 'inclusive	'
+ nslookup specify 10.0.0.1
+ grep -m 1 arpa
+ awk '-F ' '{print $4}'
+ FQDN=
+ '['  '!=' find ]
+ echo 'specify	'
+ nslookup These 10.0.0.1
+ grep -m 1 arpa
+ awk '-F ' '{print $4}'
+ FQDN=
+ '['  '!=' find ]
+ echo 'These	'
+ nslookup command 10.0.0.1
+ grep -m 1 arpa
+ awk '-F ' '{print $4}'
+ FQDN=
+ '['  '!=' find ]
+ echo 'command	'
+ nslookup use 10.0.0.1
+ grep -m 1 arpa
+ awk '-F ' '{print $4}'
+ FQDN=
+ '['  '!=' find ]
+ echo 'use	'
+ nslookup Report 10.0.0.1
+ grep -m 1 arpa
+ awk '-F ' '{print $4}'
+ FQDN=
+ '['  '!=' find ]
+ echo 'Report	'
+ nslookup See 10.0.0.1
+ grep -m 1 arpa
+ awk '-F ' '{print $4}'
+ FQDN=
+ '['  '!=' find ]
+ echo 'See	'

Please show the complete output of ip r preserving the formatting.

default via 10.0.0.1 dev br-lan proto static src 10.0.0.4 
10.0.0.0/24 dev br-lan proto kernel scope link src 10.0.0.4 
192.168.192.0/24 dev zt7nnhhtef proto kernel scope link src 192.168.192.4 

Different from mine :wink:
Please remove the space before src, so

LANNET=`ip r | grep "link\s\+ src $LANIP" | awk -F ' ' '{print $1}'`

becomes

LANNET=`ip r | grep "link\s\+src $LANIP" | awk -F ' ' '{print $1}'`
or
LANNET=`ip r | grep "link\s* src $LANIP" | awk -F ' ' '{print $1}'`
2 Likes

That did the trick! Thanks a ton for the help!

Great. It was partially my mistake, I've tested the script on the AP running a snapshot version and I have a slightly different output of ip r there.

@xNUTx please update the script with the two changes discussed ("" and space)

1 Like

Both methods, the script and the cronjob, work for me. So thanks for the solutions! What remains weird is that the frontend Associated Stations host column mostly displays the ip-address of each station, and randomly showing the hostname for a short moment. That's probably a frontend issue and as such not directly related to this topic. I wonder if anyone else observes the same.

EDIT: this is solved by the script below

Modification done :+1:t2: :slight_smile:

1 Like

For me the name resolution from the hosts files did not work reliably. Some hostnames showed up on LUCI, some stayed as IP address regardless of the properly populated hosts and ethers files.

Inspired by the script of OP I came up with the following stationinfo.sh
My network uses more VLANs, hence it handles more interfaces.
It is not so much automated, so one has to edit the value of RANGES but in case someone finds this thread I suppose he/she knows how to do it.

#!/bin/sh
# Edit the value of RANGES below according to your environment
#
RANGES='br-iot 192.168.X.1-192.168.X.253
br-guest 192.168.Y.1-192.168.Y.253
br-lan 192.168.Z.1-192.168.Z.253'

# Do not edit below

# Move ethers to ram disk to avoid wearing off of the flash
if [ ! -e "/tmp/etc/ethers" ]; then
        if [ -L "/etc/ethers" ]; then
                touch /tmp/etc/ethers
        else
                mv /etc/ethers /tmp/etc/ethers
        fi
        ln -s /tmp/etc/ethers /etc/ethers
fi

# Clear ethers
echo > /etc/ethers

arpscan2ethers() {
  while read -r IP MAC; do
    RES=$(nslookup $IP | grep 'name =')
    echo "$MAC ${RES##* }" >> /etc/ethers
  done
}

echo "$RANGES" | while read INT RANGE; do
  arp-scan -q -x -I $INT $RANGE 2>/dev/null | arpscan2ethers
done

4 Likes

Now this seems to work properly; it results in the hostname being displayed. Apparently the aforementioned solutions populate:

  • /etc/ethers with mac-address ip-address
  • /etc/hosts with ip-address hostname

and they result in hostnames constantly appearing and disappearing. Wierd. Your scripts populates:

  • etc/ethers with mac-address hostname

Thanks!

I have a few suggestions here.
First off there's no need to flll /etc/ethers & co with entries which don't get deleted. But let's start from the beginning. It all started with this right? arp-scan -qxlN -I br-lan | awk '{print $1}' | xargs fping -q -c1

So let's ee what this comman does: It does an arp ping to all possible IPs, creating a list of IP and MAC adresses found. Then it takes this list, removes the MAC adresses and does an ARP ping to the IPs.
So why are we doing two ARP pings here? Cause fping does reverse DNS lookups, too. arp-scan can do reverse DNS too, through, so the command can be reduced to arp-scan -qxdlN -I br-lan.
Now when you add that to a cron job you'll notie that it shows IPs but not hostnames. Cause of this people came up with killing NAND by writing to files on it, then moved said files to RAM and stuff... All overly compilcated cause the real issue here is that OpenWRTs DNS server tries to do reverse DNS by itself instead of asking the upper DNS server like it does for normal queries. There's a workaround for this through: Just add a custom DNS rule like this /*.in-addr.arpa/192.168.178.1 (make sure to replace 192.168.178.1 with the IP of your upper/main DNS server) and reverse DNS queries will be resolved correctly.

tl;dr:
No need for a bunch of scripts and creating files. Just do this instead:
image

image

And you'll get:

5 Likes

Tried and works, ...

... except some of my clients only have ipv6 adresses (at least that's the only thing that shows in LuCI) and for those, host names are not resolved. (I don't know how to assign ipv4 to those clients as well. Am reluctant to completely disable ipv6 to force ipv4, because I am not sure if that will work. Not a good time right now. You do not simply provoke family members complaints)

Ignore my comment, I executed wrongly.

Thanks for this nice and elegant solution.

But, with these settings (on the AP):

image
image
192.168.1.1 is my router (is that correct? It runs DNS HTTPS proxy)

I get this:

Wed May 10 20:22:00 2023 cron.err crond[7689]: USER root pid 7935 cmd arp-scan -qxdlN -I br-lan
Wed May 10 20:22:00 2023 kern.info kernel: [286913.823994] device br-lan entered promiscuous mode
Wed May 10 20:22:02 2023 kern.info kernel: [286915.694583] device br-lan left promiscuous mode

Suppose that's not right.

That's normal: It logs the command executed (no idea why it logs it as error) and the arp-scan itself somehow needs promiscuous mode and takes around two seconds to complete. So as logs are just as expected: Are the clients shown with IPv4 addys and hostnames? If so it works. :slight_smile:

What timer did you set the cronjob to and did you wait untill it runned for the next time? Remember: It adds new IPv4 addys and hostnames to the ARP and DNS caches whenever running the cronjob but unknown clients will show IPv6 only (or "?", depending on other configs) untill the next run.

Oh my bad then. I got confused by the explanation. I thought the cron job was not necessary anymore and /*.in-addr.arpa/192.168.178.1 was enough. Also, after reading a little bit more of the thread, I noticed it is required to have the arp-scan and fping packages installed, which i had not xD

I take it, when executing */2 * * * * arp-scan -qxdlN -I br-lan it is still needed to execute other commands to utilize ram or other types of memory to prevent NAND death or is that cron-job actually enough?

1 Like

It still is neccessary, it just has been simplified.

The cron job + the DNS setting is enough. It will use the normal ARP cache of Linux and the cache of OpenWRTs DNS server which are both in RAM. It's just normal network utilisation, so no need to worry about NAND aging or anything.

1 Like

Running the arp-scan manually results in a table with ip addresses and mac addresses, so that seems to work OK.

Running the arp-scan as sheduled task still show up the same as before, like:

Do you think that my DNS forwarding to 192.168.1.1 is OK?

Is fping required?

@Jack007 Running it manually should show host names and MAC addys. Could you take one of the IPs the arp-scan returns and execute nslookup [IP from arp-scan] 192.168.1.1 as well as nslookup [IP from arp-scan] please? Just for reference, this is how it looks for me (using the IP of my mobile phone) :

root@OpenWrt:~# nslookup 192.168.178.42 192.168.178.1
Server:         192.168.178.1
Address:        192.168.178.1:53

42.178.168.192.in-addr.arpa     name = POCO-M4-Pro.fritz.box

root@OpenWrt:~# nslookup 192.168.178.42
Server:         127.0.0.1
Address:        127.0.0.1:53

42.178.168.192.in-addr.arpa     name = POCO-M4-Pro.fritz.box

root@OpenWrt:~# arp-scan -qxdlN -I br-lan | grep POCO
POCO-M4-Pro.fritz.box   50:da:d6:c3:db:b1

No. The ping/scan part seems to work correctly, the reverse DNS lookups seem to fail. The commands above will hopefully help figuring out why.