Quel serait le meilleur moyen de reconnaître un serveur lorsqu'un périphérique mobile spécifique (téléphone portable, iPad, etc.) se connecte au réseau (sans fil, bien sûr)?
À titre d'exemple, une personne a son réseau Wi-Fi domestique correctement configuré sur son téléphone portable. Lorsqu'il se trouve à portée du routeur, il se connecte (rien de nouveau à ce sujet). Lors de la connexion à ce routeur, son serveur domestique lancera un programme donné (ou émettra une notification, écrira dans un fichier, etc.).
Je pensais qu'une solution possible serait une "application Web" personnalisée hébergée sur le réseau, qui serait lancée à partir du téléphone afin que le serveur reconnaisse l'appel de la page. Toutefois, si cela pouvait être fait lorsque le téléphone se connecte automatiquement, ce serait mieux.
Toutes les pensées ou solutions alternatives seraient grandement appréciées, alors merci d'avance!
Je pense que ceci peut être facilement accompli par arp-scan
.
Installez arp-scan
: Sudo apt-get install arp-scan
Détecter tous les hôtes du réseau local: Sudo arp-scan -l
Vous pouvez configurer une crontab pour exécuter périodiquement (toutes les 2 minutes peut-être) un script qui analyse le réseau avec arp-scan et analyse sa sortie pour découvrir les hôtes actifs.
Parfois, j'avais besoin du drapeau -r 3
, qui l'exécutait trois fois; fonctionne beaucoup mieux que la valeur par défaut 2 fois, ce qui manque parfois certains appareils. Ainsi:
Sudo arp-scan -l -r 3 | grep {Phone Static Assigned IP}
fonctionne mieux pour moi à LG V30 +.
import subprocess
if __== '__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!"
De cette façon, vous pouvez rechercher le MAC de votre appareil :)
J'envisage en réalité de mettre en place une solution qui réponde aux exigences suivantes:
Mon intention est de monter le système de fichiers phones avec ssh, mais il pourrait être utilisé pour n'importe quoi.
Disons que le réseau local est 192.168.1.0 ...
Donc, je mettrais en œuvre une application qui écoute les émissions UDP à partir de l’adresse de diffusion: 192.168.1.255
. Cette application ne viderait pas la batterie car elle est totalement passive. (il ne devient actif que lorsqu'un paquet est reçu).
Un démon sur l'ordinateur enverra périodiquement des émissions à l'adresse de diffusion 192.168.1.255
. Le téléphone répondra à ces signaux en indiquant son nom, son identifiant, son adresse IP, etc.
Maintenant, l'ordinateur sait que le téléphone existe sur le réseau et, dans mon cas, peut appeler sshfs mount.
Cela nécessite sûrement beaucoup de travail, y compris de programmation, et ce n’est pas facile. Mais je pense que ce serait la solution la plus fiable et la plus raisonnable.
Le meilleur moyen auquel je puisse penser est de donner à cet appareil une adresse IP statique et d’utiliser un simple script pour envoyer une requête ping à l’appareil toutes les X secondes et déclencher votre programme/notification.
Points à noter: De nombreux téléphones ne se connecteront pas au réseau wifi avant la fin du sommeil. Votre script devra pouvoir faire la différence entre le téléphone qui va se coucher et le téléphone qui quitte la maison, en tenant éventuellement compte de l'heure. Après cela, le script déclenche l'exécution d'un programme ou l'affichage d'une notification est trivial.
J'ai écrit un script qui fait quelque chose de similaire en utilisant arp-scan et une adresse IP statique sur un iPhone.
Vous pouvez trouver le code ici: https://github.com/blackairplane/pydetect
Cela doit être nettoyé car je suis nouveau sur Python, mais je pense que cela illustre le concept.
J'ai eu deux solutions que j'ai utilisées. (Python)
Le premier a été de déterminer les numéros d'ip connus que je veux suivre. Je l'ai fait en trois étapes. 1 # utilisez "-c1" pour n’envoyer qu’un seul ping.Si le périphérique est actif, il répondra et. La fonction se terminera avec succès 2 # utilisez "-c3" lui donne plus de temps pour répondre sur l’un des trois. C'est généralement suffisant lorsqu'il s'agit d'un mauvais signal wifi. 3 # utilisation "-c10" cela peut être nécessaire quand le signal wifi est vraiment mauvais. (Remarquez que l'ancien iPad a besoin d'environ 10 tentatives de réponse). Pour accélérer les choses, j'ai créé des processus distincts pour chaque numéro d'adresse IP que je souhaite suivre.
J'ai également changé les intervalles de ping selon que c'est un succès ou non. S'il trouve le périphérique, il attendra plus longtemps jusqu'à ce qu'il vérifie à nouveau. Si c'est un échec, il réessayera dans 60 secondes. (Je veux que la lumière soit allumée quand je rentre chez moi) alors 60 ans suffisent pour me retrouver dans la rue
Cela a fonctionné parfaitement! Quand je suis rentré à la maison, il m'a senti et a éteint la lumière et s'est éteint quand je suis parti.
Arping n'est peut-être pas lourd sur le réseau, mais j'ai modifié la solution pour ignorer toutes les pings et j'ai créé mon propre serveur DHCP sur mon Raspberry Pi.
J'ai ensuite ajouté "on commit" qui déclenche un script dès qu'un périphérique obtient un ipnumber. Ce script utilise un "appel API curl http" pour notifier mon serveur www (Flask) dès qu'un périphérique obtient ou renouvelle son numéro ip.
Sur mon Android j'ai modifié les paramètres pour ne jamais désactiver le wifi lorsque l'écran est éteint. Je ne sais pas si c'est possible sur iPhone. Pas de grande différence sur la batterie (OnePlus 5)
La première solution comprenait également le balayage Bluetooth pour un Mac spécifique. Ainsi, même si mon WiFi est désactivé sur mon téléphone, le Bluetooth sera toujours détecté. L'utilisation de l'adresse Mac ne nécessite pas de la coupler ou de la rendre accessible à tous.
Je suis tombé sur cela et comme j'ai déjà fait quelque chose de similaire a décidé de poster une réponse.
J'ai fait ce qui suit:
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.
Dans mon cas, un serveur HTTP s'exécutait sur mon appareil. Je viens donc d'envoyer une requête HTTP HEAD pour essentiellement rien sur le port 80. Si le périphérique répond et que l'en-tête du serveur est correctement nommé, il s'agit de mon périphérique.
Mais je ne pouvais pas aller vite sans cingler. HTTP est TCP et la demande est importante. Par conséquent, les délais d'attente doivent être de 4 secondes pour le WiFi. Faire cela pour 253 adresses est lent comme l'enfer. Mais vous n'auriez pas 253 périphériques (probablement) plus moins de serveurs HTTP. (ou dans votre cas, les téléphones)
Considérer les journaux de routeur est une très bonne idée, et facile. Et même plus rapide que de cingler tous. Certains routeurs n'ont même pas besoin de se connecter pour y accéder.
En outre, il est utile de vérifier si votre appareil prend en charge le protocole UPNP. Si tel est le cas, vous pouvez utiliser UPNP pour détecter sa présence. Ce serait une solution officielle (écouter en diffusion des UDP de l'UPNP). Mais tous les appareils ne le supportent pas. Mais tous les appareils ne supportent pas ICMP également. (ils ne souhaitent pas être bombardés inutilement).
Il y a une autre possibilité intéressante. Vous pouvez rechercher des paquets DHCP et voir quand un routeur attribue une adresse IP à un nouveau périphérique. Mais cela ne fonctionnerait pas pour les appareils avec des adresses IP statiques. Ils ne toucheraient même pas le réseau tant qu'ils n'auraient pas besoin de quelque chose. La connexion au WiFi se trouve sur une autre couche et ne peut pas être facilement détectée à moins que vous ne souhaitiez agir comme renifleur. Je ne suis pas sûr même si c'est faisable avec la carte réseau dans un mode promisquous. Je pense que du matériel supplémentaire serait nécessaire pour cela.
Pour réaliser un ping en Python, sans sous-traitement du programme ping et sans perte de vitesse, vous devez créer un socket brut et construire manuellement un paquet ICMP. Ce n'est pas difficile Il en existe un exemple quelque part sur le Web. Bien sûr, pour l’envoyer, vous aurez besoin d’autorisations root, tout comme le ping. Ceci est un inconvénient. Si vous distribuez le logiciel, vous ne pouvez pas vous attendre à ce que les utilisateurs veuillent l'exécuter en tant que root.