Ottenere l'indirizzo MAC da dispositivi con Python
-
20-09-2019 - |
Domanda
Sto cercando un modo (con python) per ottenere l'indirizzo layer II
da un dispositivo sulla mia rete locale. indirizzi Layer III
sono note.
L'obiettivo è quello di costruire uno script che il polling un database di indirizzi IP ad intervalli regolari per garantire che gli indirizzi MAC non sono cambiate e se hanno, avvisi e-mail a me stesso.
Soluzione
Per rispondere alla domanda con Python dipende dalla vostra piattaforma. Non ho di Windows a portata di mano, in modo dalla seguente soluzione funziona su Linux box ho scritto su. Un piccolo cambiamento per l'espressione regolare sarà farlo funzionare in OS X.
In primo luogo, è necessario eseguire il ping il bersaglio. Che posizionare il bersaglio - fino a quando è all'interno della vostra maschera di rete, il che suona come in questa situazione sarà - nella cache ARP del sistema. Osservare:
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
Sapendo che, si fa un po 'di magia sottoprocesso - altrimenti si sta scrivendo cache ARP controllo codice da soli, e non si vuole fare che:
>>> 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"
Altri suggerimenti
C'è stato un domanda simile non si risponde troppo lungo fa su questo sito. Come accennato nella risposta scelto dal richiedente di tale questione, Python non ha un built-in modo di farlo. È necessario sia richiamare un comando di sistema come arp
per ottenere informazioni ARP, o generare i propri pacchetti usando Scapy .
Modifica Un esempio utilizzando Scapy dal loro sito web :
Ecco un altro strumento che monitorare costantemente tutte le interfacce su un macchina e stampare tutti ARP fa richiesta vede, anche su 802.11 fotogrammi da un scheda Wi-Fi in modalità monitor. Notare la store = 0 parametro sniff () per evitare memorizzare tutti i pacchetti nella memoria per nulla.
#! /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)
Non è esattamente quello che stai cercando, ma sicuramente sulla strada giusta. Buon divertimento!
Sembra che si desidera monitorare spoofer ARP? In questo caso, tutto ciò che serve è arpwatch , disponibile in ogni distribuzione Linux ben fornita vicino a te . fonti per il download qui: http://ee.lbl.gov/
per i sistemi basati su 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)
lista di tuple con i Mac tornerà. Scapy è uno strumento incredibile, ma sembra essere eccessivo per questo caso
In Linux sometimems si dimentica la linea di comando util "arp". immagine ambiente Linux embedded Una base Yocto per esempio.
Un modo alternativo senza la funzione "arp" sarebbe quello di leggere e analizzare il file / 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
un modo più semplice, se su linux:
print os.system('arp -n ' + str(remoteIP))
si otterrà:
Address HWtype HWaddress Flags Mask Iface
192.168..... ether 9B:39:15:f2:45:51 C wlan0
Una soluzione semplice utilizzando Scapy, per la scansione di sottorete 192.168.0.0/24 è la seguente:
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))
Prova ad utilizzare i netifaces trovate qui. netifaces
Aggiornamento generale per Python 3.7. Nota: l'opzione per la -n
arp
non fornisce la lista arp sui sistemi Windows, come previsto con risposte certe per i sistemi basati su Linux. Utilizzare l'opzione -a
come indicato nella risposta qui.
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))