Question

Je suis à la recherche d'un moyen (avec python) pour obtenir l'adresse de layer II à partir d'un périphérique sur mon réseau local. adresses Layer III sont connues.

Le but est de construire un script qui Interroger les bases de données d'adresses IP à intervalles réguliers assurant que les adresses MAC n'ont pas changé et si elles ont, alertes e-mail à moi-même.

Était-ce utile?

La solution

Pour répondre à la question avec Python dépend de votre plate-forme. Je n'ai pas de Windows à portée de main, donc la solution suivante fonctionne sur la boîte Linux je l'ai écrit sur. Un petit changement à l'expression régulière fera fonctionner sous Mac OS X.

D'abord, vous devez ping la cible. Cela placera la cible - tant qu'il est dans votre masque de réseau, qu'il sonne comme dans cette situation, il sera - 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 que, vous faites un peu de magie subprocess - sinon vous écrivez du code de vérification du cache ARP vous, et vous ne voulez pas faire cela:

>>> 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"

Autres conseils

Il y avait un question similaire répond pas trop longtemps Il y a sur ce site. Comme mentionné dans la réponse choisie par le demandeur de cette question, Python ne dispose pas d'une manière intégrée pour le faire. Vous devez soit appeler une commande de système tel que arp pour obtenir des informations ARP, ou générer vos propres paquets en utilisant Scapy .

Modifier Un exemple en utilisant Scapy de leur site web :

  

Voici un autre outil qui   surveiller en permanence toutes les interfaces sur un   machine et imprimer toutes les demandes ARP il   voit, même sur les trames 802.11 d'une   Carte Wi-Fi en mode moniteur. Noter la   store = 0 paramètre à reniflement () pour éviter   stocker tous les paquets dans la 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)

Pas exactement ce que vous cherchez, mais certainement sur la bonne voie. Amusez-vous!

On dirait que vous voulez surveiller usurpateurs ARP? Dans ce cas, tout ce que vous avez besoin est arpwatch , disponible dans toutes les distributions Linux bien fourni près de chez vous . Télécharger les sources ici: http://ee.lbl.gov/

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)

renvoie la liste des tuples avec macs. scapy est un outil extraordinaire, mais semble être surpuissant pour ce cas

Linux vous sometimems manquez la ligne de commande util "arp". L'image de l'environnement embarqué linux par exemple d'un base.

Une autre façon 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

d'une manière plus facile, si sur linux:

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

vous obtiendrez:

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

Une solution simple à l'aide 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))

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

Mise à jour générale pour Python 3.7. Remarque: l'option -n pour arp ne fournit pas la liste des arp sur les systèmes Windows comme prévu certaines réponses pour les systèmes à base de Linux. Utilisez l'option -a comme indiqué dans la réponse ici.

from subprocess import Popen, PIPE

pid = Popen(['arp', '-a', ip], stdout=PIPE, stderr=PIPE)

IP, MAC, var = ((pid.communicate()[0].decode('utf-8').split('Type\r\n'))[1]).split('     ')
IP  =  IP.strip(' ')
MAC =  MAC.strip(' ')

if ip == IP:
    print ('Remote Host : %s\n        MAC : %s' % (IP, MAC))
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top