What would be the best way to have a server recognize when a specific mobile device (cell phone, iPad, etc.) connects to the network (wirelessly, of course)?

As an example situation, a person has his home wifi network properly configured on his cellphone. When he gets within range of the router, it would connect (nothing new about that). Upon connection to that router, his home server would launch a certain program (or throw a notification, write to a file, etc.).

I thought that a possible solution would be a network-hosted custom "web app" that would be launched from the phone so that the server would recognize the page was called. However, if this could be done when the phone connects automatically, that would be best.

Any thoughts or alternate solutions would be greatly appreciated, so thanks in advance!

  • If it is an android phone a cron job wgetting a local website would be easiest. To do it from the network side you would have to use RADIUS protocol and have a properly setup RADIUS server. – Huckle May 27 '12 at 23:18
  • Why not just review your router logs. Since these logs are text based it would be easy to query the logs and get only the information you need. Surely someone has written the code to do this but if not it would be a simple exercise. – user501548 Feb 3 '16 at 22:51

I think this can be easily accomplished by arp-scan.

Install arp-scan: sudo apt-get install arp-scan
Detect all the hosts on the local network: sudo arp-scan -l

You can set up a crontab to periodically (every 2 mins maybe) run a script that scans the network with arp-scan and parses its output to discover the active hosts.

  • It should be noted that some devices might not show up unless they are turned on. My nexus 4 won't show up unless the screen is on. – Nicolas Bouliane May 19 '14 at 2:00
import subprocess

if __name__ == '__main__':
    while True:
        sleep(5)
        p = subprocess.Popen("arp-scan -l | grep xx:xx:xx:xx:xx:xx", stdout=subprocess.PIPE, shell=True)
        (output, err) = p.communicate()
        p_status = p.wait()
        if output:
            print "Yay, the devine is connected to your network!"
        else:
            print "The device is not present!"

This way you can scan for the MAC of your device :)

I am actually contemplating to implement a solution for this that meets following requirements:

  1. The phone does not need to have assigned IP address on the network.
  2. The phone does not need to periodically send out signals that would drain its battery.
  3. If there are many phones on the network, all of them would be detected.

My intention is to mount the phones filesystem with ssh, but it could be used for whatever.

Let's say the local network is 192.168.1.0...

So I would implement an APP that listens to UDP broadcasts from the broadcast address: 192.168.1.255. This app would not drain battery as it totally passive. (it only gets active when a packet is received).

A daemon on the computer will will periodically send out broadcasts to the broadcast address 192.168.1.255. The phone will reply to such signals giving its name, id, ip address etc.

Now the computer know that the phone exists on the network and for my case can invoke sshfs mount.

Surely this needs a lot of work, including programming work, and is not easy. But I think it would be the most reliable and reasonable solution.

  • 1
    Wow, so basically a custom protocol... one would think there would exist something like this already. – Michael Jan 29 '17 at 1:31

The best way I can think of is to give said device a static IP address, and use a simply script to ping the device every X seconds and trigger your program / notification.

Things to note: Many phones won't connect to the wifi network until the wake up from sleep. Your script will need to be able to tell the difference between the phone going to sleep and the phone leaving the house, possibly by considering the time of day. After that, having the script trigger a program to run or a notification to appear is trivial.

I wrote a script that does something similar using arp-scan and a static IP address on an iPhone.

You can find the code here: https://github.com/blackairplane/pydetect

It needs to be cleaned up as I am new to Python, but I think it illustrates the concept.

I stumbled on this and as I once did something similar decided to post an answer.

I did the following:

1. Ping all addresses within given network and subnet (excluding network and broadcast addresses)
2. Wait for response has a timeout so that if device doesn't answer from furthest corner of your WiFi it is considered not present.
3. So we get all IPs on the net that answer to ICMP packets.
4. Then use each detected IP to ask for more and decide which device you like and which one you don't.

In my case I had an HTTP server running on my device. So I just sent HTTP HEAD request for essentially nothing on port 80. If device responded and Server header is properly named, then this is my device.

But I couldn't go fast without pinging first. HTTP is TCP and request is big, so timeouts have to be 4 seconds for WiFi. Doing this for 253 addresses is slow as hell. But you wouldn't have 253 devices (probably) more less HTTP servers. (or in your case, phones)

Considering router logs is very good idea, and easy. And even faster than pinging all. Some routers do not even need logging in for getting to them.

Also, it is worth checking whether your device has UPNP support. If it does, you can use UPNP to detect its presence. This would be official solution (listening on broadcast for UDPs of UPNP). But all devices does not support it. But all devices do not support ICMP also. (they don't wish to be bombarded needlessly).

There is another interesting possibility. You can fish for DHCP packets and see when a router is giving a new device an IP address. But this wouldn't work for devices with static IPs. They wouldn't even touch the network until they need something. Connecting to WiFi itself is on another layer and cannot be easily detected unless you wish to act as a sniffer. I am not sure even if it is doable with network adapter in a promisquous mode. I think additional hardware would be needed for this.

To achieve ping in Python, without subprocessing to ping program and losing speed, you have to create raw socket and construct ICMP packet manually. It is not hard. There is example of it somewhere on the web. Of course, to send it you will need root permissions as does the ping. This is a drawback. If you will distribute the software you cannot expect users to want to run it as root.

I had two solutions that I used. (Python)

Solution 1

First was to arping known ipnumbers that I want to track. I did this in three steps. 1# use "-c1" to only send one ping.if the device is active it will reply and. The function will exit with success 2# use "-c3" now give it more time to reply on one of three. This is usually enough when it's a poor wifi signal. 3# use "-c10" this might be needed when it's really bad wifi signal. (Noticed the old iPad needs about 10 tries to answer) To speed up things I created separate Processes for each ip number I want to track.

I also changed the pinging intervals depending on if it's a success or not. If it finds the device it will wait longer until it checks again. If it's a failure it will try again in 60 seconds. (I want the light on when I enter my home) so 60s is enough to find me on the street

This worked perfectly! When I got home it sensed me and turned out the light, and off when I left.

Solution 2

Arping might not be heavy on the network but I changed the solution to skip all pings and created my own DHCP server on my raspberry pi.

I then added "on commit" which trigger a script as soon as a device gets an ipnumber. This script use a 'curl http API call' to notify my www server (Flask) as soon as a device gets or renew it's ipnumber.

On my Android I changed the settings to never turn off wifi when the screen is off. Not sure if it's possible on iPhone. No big difference on battery (OnePlus 5)

The first solution also included Bluetooth scanning for specific Mac. So even if my WiFi is off on my phone it will still sense the Bluetooth. Using Mac address don't need to pair it or have it available for everyone to see.

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.