Enumerating LAN and WLAN clients on a Linux router
A while ago I was asked to take a WiFi router and add some bell and whistles to its interface. It was one of those small NAT boxes – nothing more than a LAN switch and a WLAN access point strapped to a 200 MHz system-on-a-chip running Linux. ucLinux, to be exact.
The exact request was “list all the computers connected to our box – wired and wireless”. Not a lot of info – MAC, IP address, Windows computer name. But what does “connected” actually mean?
This wasn’t much of a question for the marketing people. Ideally, if you put a cable in the router, the computer will show as connected. Take the cable out, and it should show no more. Well, a lot easier said than done.
It’s easy to be accurate on the wireless side. The driver for the Marvell wireless chipset can be queried for the active connections, and you can retrieve the active MACs from /proc/net/mvwlan.
You still need to see the IP address of those wireless machines, and there are a couple of places where one could look. One is the ARP cache (live at /proc/net/arp) . But this is a short term memory, cleared every few minutes – so you better store the results before they are gone.
Another help comes from the DHCP server. In my case I used the udhcp – 28 kbytes of highly packed ARM code. Small size is importat when you fight with the UI people for every little bit of flash ROM. Well, this little fella will save a binary stream of leased addresses and Windows names at /var/lib/misc/udhcpd.leases . Of course, this does not work with static IPs, and due to the 24h lease expiry time, the information there is sometimes stale.
Now things get a bit wilder on the wired side . Theoretically, you can have a computer that sits somewhere completely silent and undetectable. So I had to sniff traces of every move.
ARP and DHCP are obvious sources – but ARP results die fast, while DHCP will stay there forever. And a curious side effect happens when someone logs on wirelessly and then quits: its DHCP lease will still be there, and, if there’s no record of where the packets came from, a naive implementation will show that the machine still connected – on the LAN side, of course. That brings the user into confusion and distrust.
NAT connections (/proc/net/ip_conntrack) will give you highly useful information on who is active and connecting from the LAN to the WAN side of the box. If they are available on your distribution – not in my case.
And the most accurate way to do record connections, if you have programming time and cycles to spare, is to capture the packets that come through the LAN interface and store the statistics somewhere. Not an easy task, though.
Another idea is to make the router a bit more active and ask it to ping its guests. Except that a firewall like the default WinXP sp 2 would block your echo requests.
And if you still have to get Windows names of static IPs, you’ll have to craft a SMB query to that address. But then again, if you see the router scanning the network, would you trust it anymore?