Wednesday, February 4, 2015

Checking devices connected to the LAN

One thing that could be useful is checking if a device is connected to your LAN at home.

This is a quite simple task and could be used for several goals, from sending you a Whatsapp greeting message when you arrive at home to inform you in case of undesired connection to your own wi-fi network.

To check for a specific device You just need to know its MAC address. This could be easily retrieved from the network itself when the device is connected.

The MAC address will not change as normally do the IP address between different connections and it's unique, so it can be reliably used to perform this check.

The first thing we have to do is installing Nmap:

sudo apt-get install nmap

This software scans the LAN and gives back several data, including MAC addresses. Now we can try a default scan as listed in the nmap help:

nmap -sn 192.168.0.0/24

This command assumes that your LAN has that address range (192.168.0.1-192.168.0.255). Of course you need to change the address accordingly to your setup.

This is an output example:

Starting Nmap 6.00 ( http://nmap.org ) at 2015-02-04 10:41 CET
Nmap scan report for 192.168.0.1
Host is up (0.015s latency).
Nmap scan report for 192.168.0.2
Host is up (0.045s latency).
Nmap scan report for 192.168.0.3
Host is up (0.026s latency).

The first thing we can note is that this command takes long time to complete. This is because it's scanning all the 256 addresses. If we do not need to scan all of them we can reduce that time a lot.

The second thing is that we get info just about the IP addresses and no MAC is shown. The problem is that MAC addresses can be retrieved only by root. So let's try this:

sudo nmap -sn 192.168.0.0/16

Now the result is a bit different:

Starting Nmap 6.00 ( http://nmap.org ) at 2015-02-04 10:50 CET
Nmap scan report for 192.168.0.1
Host is up (0.0050s latency).
MAC Address: 00:00:00:00:00:00 (Unknown)
Nmap scan report for 192.168.0.2
Host is up (0.33s latency).
MAC Address: 00:00:00:00:00:00 (Raspberry Pi Foundation)
Nmap scan report for 192.168.0.3
Host is up.

I changed the shown MACs because I prefer to keep mine private, but you can see that for every device (apart from the first one that is the router) you have the MAC address and a description if the device can provide it (note the RPi).

If you have a lot of devices connected to your LAN however, it could be quite difficult to associate the MAC addresses. You can make it easier by checking Nmap output before and after connecting the device You need to find.

As I already said, the time required to perform a full LAN check is too much (at least for my needs), so I decided to check just a small part of it as my address pool has been limited to just 50 addresses in the router.

You can then specify a smaller range when invoking Nmap:

sudo nmap -sn 192.168.0.0-50

This will scan just the first 50 IP addresses, taking less time. You can adjust that range for your needs of course.
Now we can use this command inside our automation script. Let's try to get a greeting when our smartphone connects to the LAN...

First of all we are going to use the subprocess library, so at the top of our script we need to add:

import subprocess

Then we should add three variables. These will be used to check if the smartphone has just connected (to avoid sending the greeting continuosly) and to count how much time it has been disconnected to avoid sending the message after a too short disconnection. The second is needed because most smartphones disconnect when locked and reconnect for a short time when they need to perform some internet connection.
The third one is just the MAC address we wish to check.

counter=0 # Counter for disconnected phone
status=0 # Status of connection
mac="00:00:00:00:00:00"

At the end of our script (but inside the while cycle) add the following code:

    result=subprocess.check_output("sudo nmap -sn 192.168.0.0-50", shell=True)
    if (mac in result) and (status==0): # At the first connection sends a welcome message
        Answer("Welcome back!")
        status=1
    if (mac in result) and (status==1): # If phone connected keeps the counter reset
        counter=0
    if (mac not in result) and (status==1): # If phone is not connected increase the counter
        counter=counter+1
    if (status==1) and (counter>360): # Wait for the phone to stay disconnected for a while
        status=0
        counter=0

With the subprocess statement we can execute Nmap and get its output back in a variable. Then we just need to check if our MAC address is inside that variable. If it's found, then the device is connected.
The counter test waits for the device to stay disconnected for at least an hour consecutively, before it can send the message again when it connects again. You can change that number and add a small delay to adjust this time.

Similarly you can check if there is a device inside your LAN that is not in a list of MAC addresses and then send a Whatsapp message to inform you about this connection.

7 comments:

  1. A little suggestion to boost up the speed of nmap is to change -sn to -sP.
    Which simply ping the host and can return mac address and ip at the same time.
    Thank you for sharing this handy skill.
    Thank you

    ReplyDelete
  2. hello, i want to ask you, are u using crontab to execute this code periodically?
    if u do so, how u keep the same value for counter and status on every run?
    cz when the code lunches status and counter will be equal to 0 everytime, so what to do ?

    ReplyDelete
    Replies
    1. No, this code is always active as it's part of the parser script (launched at boot), so I have no problems with the counter.

      Delete
  3. Hi Carlo, your article is very interesting, but I have doubt about the script, which kind of script are you talking about? where should it be placed?
    Thanks for your help

    ReplyDelete
    Replies
    1. Thanks! The parts starting from "import subprocess" should be put in the Python script I prepared in a previous post about Yowsup (Whatsapp): "Using whatsapp for home automation - The parser".
      Of course you can use these parts in your own scripts...

      Delete
  4. I stuck ... I try to do this but it doesen't work with my iPhone, it works with other devices in my Network. My iPhone doesent respond to an ICMP request, it's maybe that the Problem?

    ReplyDelete
    Replies
    1. I don't think that's the problem. I also have in iPhone and it works without issues (at least with ios 8 and ios 9).
      The only problem you should find with iDevices is that when the device is on standby it disconnects from the wi-fi and reconnects every few minutes for the apps that need a connection (i.e. whatsapp, facebook, etc.)
      Did you try to ping the iPhone directly (ping <>)?

      Delete