Thursday, July 10, 2014

Detecting WiFi clients on TP-LINK routers using Python and telnetlib

Inspired by this project on Hackaday where submitter Mattia used Python to nmap scan his WiFi network, triggering alerts when particular MAC addresses are found, and with my dreams of home-automation in mind, I came up with a slightly different way of achieving the same thing.

My router is a cheapo TP-LINK, but it does come with a "currently connected MAC addresses" page in the web interface so my first thought was using BeautifulSoup to do some parsing. Then I found references to a telnet interface.

Connecting to the Telnet interface I quickly found that the command "wlctl assoclistinfo" gave me this output:

Associated stations:4
Num     Mac Address        Time
1    F0:C1:F1:22:xx:xx    00:02:30:04
2    90:21:55:B0:xx:xx    01:02:20:26
3    00:0F:54:10:xx:xx    03:09:17:28
4    74:E1:B6:2C:xx:xx    30:04:37:48 

Firing up Python and the telnetlib telnet-automation module meant that 10 minutes later I was printing comma-separated MAC addresses to the console using this snippet of code:

Finally, I am triggering this in my Raspberry Pi via a simple crontab entry:

* * * * * logger `python /home/pi/wlan_sensor/sense.py`

This gives me per-minute logging of WiFi clients, giving me the information I need to the first of my home-automation projects - turning on the lights when I get home.

17 comments:

  1. Have you used this in your home automation project? Is it a reliable presence indicator?

    ReplyDelete
  2. Hi Gilson. It's pretty good, though there is a slight lag - about 60 seconds - before my phone connects, after I park in the driveway. This is frustrating but if I move the wireless router nearer to the front of the house I expect it will be a bit quicker.

    ReplyDelete
  3. Hi Robert, thanks for answering. Is this lag constant even if you increase the cron job frequency? Would it affect the router performance?

    ReplyDelete
  4. Hi Gilson - no probs, it's nice to get a non-spam question :-)

    The answer is yes and no... I found the response improved to about 30 seconds when running in a loop in a bash script. My telnet interface could handle at the request every 5 seconds without any issues cropping up with the router. In the end I stayed with the per-minute checks as my biggest issue was the range to the front of the house + my phone being a bit slow to connect. This gives me about a 1.5-2 minute response in the real world.

    Once I've moved the router I'll aim to speed it up a bit and I'll comment here to let you know how it turns out.

    Cheers, Robert

    ReplyDelete
  5. Hi Robert,
    I'm running a loop in Python, but have not figured out how to do so without establishing a new session every time. Is it possible?
    Thanks,
    Gilson

    ReplyDelete
  6. Hi Gilson,

    I'm not sure without testing but off the top of my head you should be able to call the tn.write("wlctl assoclistinfo\n") and tn.read_all() lines one after the other as many times as you need. I'd just print out the tn.read_all() first though as I'm not sure what output there'd be and whether my mess of lambdas would handle it...

    Cheers,
    Robert

    ReplyDelete
  7. Hi Robert,
    With or without read_all() it seems that successive calls to write("wl assoclist") and write("exit\n") result in a [Errno 32] Broken Pipe which indicates a closed connection.
    Not sure how to circuntent that yet...
    Thanks,
    Gilson

    ReplyDelete
  8. Hi Robert,
    Had to remove write("exit\n") and replace read_all() with read_until("# "). Seems logical now, doesn't it?
    Thanks,
    Gilson

    ReplyDelete
  9. Hi Gilson,
    You beat me to it, by about 5 minutes... I just finished a proof-of-concept using tn.read_very_eager(), which works too but needs a small sleep between the write(...) and it to stop unnecessary blocking. Glad you got it to work.
    Cheers,
    Robert

    ReplyDelete
  10. Hi Robert,
    I've been playing with presence detection and your article was just what I needed on the wifi front. There are other methods that use Arp or Tshark but they all have their weak points. Don't work well with iOS or are cumbersome, for example. So far reading the assoclist seems to be the best for my use case. Will let the code run for a few days to see how reliable it is and poslish it to deal with connection failures... Thank you!

    ReplyDelete
  11. Broadband speed has become a critical factor in having a reliable and enjoyable internet connection. With the birth of Internet TV, you need a good download speed to have interruptible playback. We have all at one time or another enjoyed watching a movie online only for it to constantly be 'buffering' or unable to connect.RouterReset

    ReplyDelete
  12. This comment has been removed by the author.

    ReplyDelete
  13. In the universe of blog composing, this blog really should be known as the best.
    The Best In Tech

    ReplyDelete
  14. I was even better for my iPad mini. That battery was at 95% when I left, and 89% when I returned. While catching up on podcasts on my mini, I read a few articles and managed my email.web site

    ReplyDelete
  15. When connecting a Wireless Router to the Internet and to provide a WLAN (Wireless Local Network) for local connectivity, it is important that you firstly have a working Broadband DSL connection to the Internet via a DSL modem. best wireless routers reviews

    ReplyDelete
  16. Some time ago links were utilized to organize numerous PCs together. Equipment like switches, center points, switches and so forth were required for correspondence between PCs, however Wifi brought innovative change in correspondence of PCs by giving remote network highlights.dual band vs tri band

    ReplyDelete
  17. Very good points you wrote here..Great stuff...I think you've made some truly interesting points.Keep up the good work. important link

    ReplyDelete