web-dev-qa-db-fra.com

Obtenir l'adresse MAC des périphériques utilisant Python

Je cherche un moyen (avec python) d'obtenir l'adresse de la couche II à partir d'un périphérique de mon réseau local. Les adresses de couche III sont connues.

L'objectif est de créer un script qui interrogera des bases de données d'adresses IP à intervalles réguliers, en s'assurant que les adresses mac n'ont pas changé et, le cas échéant, en envoyant des alertes par e-mail à moi-même.

16
nfarrar

Répondre à la question avec Python dépend de votre plate-forme. Je n'ai pas Windows à portée de main, donc la solution suivante fonctionne sur le système Linux sur lequel je l'ai écrite. Un petit changement à l'expression régulière le fera fonctionner sous OS X.

Tout d'abord, vous devez cingler la cible. Cela placera la cible - tant qu'elle se trouve dans votre masque de réseau, comme cela semble être le cas dans cette situation - dans le cache ARP de votre système. Observer:

13:40 jsmith@undertow% ping 97.107.138.15
PING 97.107.138.15 (97.107.138.15) 56(84) bytes of data.
64 bytes from 97.107.138.15: icmp_seq=1 ttl=64 time=1.25 ms
^C

13:40 jsmith@undertow% arp -n 97.107.138.15
Address                  HWtype  HWaddress           Flags Mask            Iface
97.107.138.15            ether   fe:fd:61:6b:8a:0f   C                     eth0

Sachant cela, vous faites un peu de magie de sous-processus - sinon, vous écrivez vous-même le code de vérification du cache ARP et vous ne voulez pas le faire:

>>> from subprocess import Popen, PIPE
>>> import re
>>> IP = "1.2.3.4"

>>> # do_ping(IP)
>>> # The time between ping and arp check must be small, as ARP may not cache long

>>> pid = Popen(["arp", "-n", IP], stdout=PIPE)
>>> s = pid.communicate()[0]
>>> mac = re.search(r"(([a-f\d]{1,2}\:){5}[a-f\d]{1,2})", s).groups()[0]
>>> mac
"fe:fd:61:6b:8a:0f"
16
Jed Smith

Il y avait une question similaire répondu il n'y a pas si longtemps sur ce site. Comme mentionné dans la réponse choisie par le demandeur de cette question, Python n'a pas de méthode intégrée pour le faire. Vous devez soit appeler une commande système telle que arp pour obtenir les informations ARP, soit générer vos propres paquets à l’aide de Scapy .

Edit: Un exemple utilisant Scapy à partir de leur site web :

Voici un autre outil qui surveillera en permanence toutes les interfaces d'une machine et imprimera toutes les demandes ARP qu'il verra, même sur des images 802.11 à partir d'une carte Wi-Fi en mode moniteur. Notez le paramètre store = 0 à renifler () pour éviter de stocker tous les paquets en mémoire pour rien.

#! /usr/bin/env python
from scapy import *

def arp_monitor_callback(pkt):
    if ARP in pkt and pkt[ARP].op in (1,2): #who-has or is-at
        return pkt.sprintf("%ARP.hwsrc% %ARP.psrc%")

sniff(prn=arp_monitor_callback, filter="arp", store=0)

Ce n'est pas exactement ce que vous recherchez, mais vous êtes sur la bonne voie. Prendre plaisir!

4
jathanism

On dirait que vous voulez surveiller les spoofers ARP? Dans ce cas, tout ce dont vous avez besoin est arpwatch , disponible dans toutes les distributions Linux bien fournies proches de chez vous. Téléchargez les sources ici: http://ee.lbl.gov/

2
intgr

pour les systèmes Unix:

#!/usr/bin/env python2.7

import re
import subprocess
arp_out =subprocess.check_output(['arp','-lan'])

re.findall(r"((\w{2,2}\:{0,1}){6})",arp_out)

retournera la liste des tuples avec macs. Scapy est un outil incroyable, mais semble être excessif pour ce cas

2
Andrei Volokitin

Dans Linux, vous manquez parfois l’utilitaire "arp" en ligne de commande. Une image de l’environnement intégré yocto linux de base, par exemple.

Une autre solution sans l'outil "arp" serait de lire et d'analyser le fichier/proc/net/arp:

root@raspberrypi:~# cat /proc/net/arp
IP address       HW type     Flags       HW address            Mask     Device
192.168.1.1      0x1         0x2         xx:xx:xx:xx:xx:xx     *        wlan0
192.168.1.33     0x1         0x2         yy:yy:yy:yy:yy:yy     *        wlan0
2
urnenfeld

Une solution simple utilisant scapy pour analyser le sous-réseau 192.168.0.0/24 est la suivante:

from scapy.all import *

ans,unans = arping("192.168.0.0/24", verbose=0)
for s,r in ans:
    print("{} {}".format(r[Ether].src,s[ARP].pdst))
1
AliA

un moyen plus facile, si sur linux:

print os.system('arp -n ' + str(remoteIP))

tu auras:

    Address        HWtype  HWaddress           Flags Mask            Iface
    192.168.....   ether   9B:39:15:f2:45:51   C                     wlan0
1
thais dbraz

Essayez d'utiliser les netifaces trouvés ici. netifaces

0
Olu Smith