wake-up-neo.net

Beziehen Sie die MAC-Adresse von Geräten mit Python

Ich suche nach einer Möglichkeit (mit Python), die Layer-II-Adresse von einem Gerät in meinem lokalen Netzwerk abzurufen. Layer III-Adressen sind bekannt.

Das Ziel ist es, ein Skript zu erstellen, das in regelmäßigen Abständen eine Datenbank mit IP-Adressen abfragt, um sicherzustellen, dass sich die Mac-Adressen nicht geändert haben, und, falls dies der Fall ist, Benachrichtigungen per E-Mail an mich selbst zu senden.

16
nfarrar

Die Beantwortung der Frage mit Python hängt von Ihrer Plattform ab. Ich habe kein Windows zur Hand, daher funktioniert die folgende Lösung auf der Linux-Box, auf der ich sie geschrieben habe. Eine kleine Änderung am regulären Ausdruck bewirkt, dass er in OS X funktioniert.

Zuerst müssen Sie das Ziel anpingen. Dadurch wird das Ziel - solange es sich in Ihrer Netzmaske befindet, wie es sich in dieser Situation anhört - im ARP-Cache Ihres Systems abgelegt. Beobachten:

13:40 [email protected]% 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 [email protected]% 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

Wenn Sie das wissen, machen Sie eine kleine Unterprozess-Magie - ansonsten schreiben Sie den Code für die Überprüfung des ARP-Cache selbst und möchten dies nicht tun:

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

Auf dieser Site wurde vor nicht allzu langer Zeit eine ähnliche Frage beantwortet. Wie in der vom Fragesteller gewählten Antwort erwähnt, verfügt Python nicht über eine eingebaute Methode, um dies zu tun. Sie müssen entweder einen Systembefehl wie arp aufrufen, um ARP-Informationen abzurufen, oder mit Scapy Ihre eigenen Pakete generieren.

Edit: Ein Beispiel mit Scapy von ihrer Website :

Hier ist ein weiteres Tool, das ständig alle Schnittstellen auf einem Computer überwacht und alle angezeigten ARP-Anforderungen druckt, selbst auf 802.11-Frames von einer Wi-Fi-Karte im Überwachungsmodus. Beachten Sie den Parameter store = 0 für sniff (), um zu vermeiden, dass alle Pakete für nichts im Speicher gespeichert werden.

#! /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)

Nicht genau das, wonach Sie suchen, aber auf jeden Fall auf dem richtigen Weg. Genießen!

4
jathanism

Klingt, als ob Sie ARP-Spoofer überwachen möchten? In diesem Fall benötigen Sie lediglich arpwatch , das in jeder gut ausgestatteten Linux-Distribution in Ihrer Nähe verfügbar ist. Hier können Sie Quellen herunterladen: http://ee.lbl.gov/

2
intgr

für Unix-basierte Systeme:

#!/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)

gibt die Liste der Tupel mit Macs zurück. scapy ist ein erstaunliches Werkzeug, scheint aber für diesen Fall übertrieben zu sein

2

Unter Linux fehlt manchmal die Befehlszeile "arp". Zum Beispiel ein Basis-Yocto-Linux-Embedded-Umgebungs-Image.

Eine alternative Möglichkeit ohne das Tool "arp" wäre das Lesen und Parsen der Datei/proc/net/arp:

[email protected]:~# 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

Eine einfache Lösung zum Scannen des Subnetzes 192.168.0.0/24 mithilfe von scapy lautet wie folgt:

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

eine einfachere Möglichkeit, wenn unter Linux:

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

sie erhalten:

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

Probieren Sie die Netifaces aus, die Sie hier finden. netifaces

0
Olu Smith

Allgemeines Update für Python 3.7. Anmerkung: die Option -n for arp bietet auf Windows-Systemen keine Arp-Liste, da bei Linux-basierten Systemen bestimmte Antworten verfügbar sind. Verwenden Sie die Option -a wie in der Antwort hier angegeben.

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))
0
ZF007