2009-11-17 292 views
14

Estoy buscando una forma (con python) para obtener la dirección de capa II desde un dispositivo en mi red local. Las direcciones de capa III son conocidas.Obtener la dirección MAC de dispositivos usando Python

El objetivo es construir una secuencia de comandos que sondeará una base de datos de direcciones IP en intervalos regulares para garantizar que las direcciones mac no hayan cambiado y, si es así, envíeme alertas por correo electrónico.

+0

Él está evitando ARP gratuito, no comprobar las cosas en la máquina local. Lea la pregunta cuidadosamente: ** desde un dispositivo en mi red local ** –

Respuesta

14

Responder a la pregunta con Python depende de su plataforma. No tengo Windows a mano, así que la siguiente solución funciona en la caja de Linux en la que la escribí. Un pequeño cambio en la expresión regular lo hará funcionar en OS X.

Primero, debe hacer ping al destino. Eso colocará el objetivo, siempre y cuando esté dentro de su máscara de red, lo que suena en esta situación, en el caché ARP de su sistema. Observe:

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 

Sabiendo eso, haces un poco de magia subproceso - de lo contrario se está escribiendo caché ARP código de comprobación de sí mismo, y no quiere hacer eso:

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

¡Esa es exactamente la respuesta que estaba escribiendo! –

+0

Si no tiene arp (que OpenWRT no) y tiene el paquete ip-neighbor (que se puede instalar en OpenWRT), puede usar este comando para obtener el valor de 'pid': ' pid = Popen (["ip", "vecino", "mostrar", IP], stdout = PIPE) ' –

2

¿Parece que quiere monitorear los spoofers de ARP? En este caso, todo lo que necesita es arpwatch, disponible en todas las distribuciones de Linux aprovisionadas cerca de usted. Descargue fuentes aquí: http://ee.lbl.gov/

3

Hubo una respuesta similar question no hace mucho en este sitio. Como se menciona en la respuesta elegida por el que hace la pregunta, Python no tiene una forma integrada de hacerlo. Debe llamar a un comando del sistema como arp para obtener información ARP o generar sus propios paquetes usando Scapy.

Editar: Un ejemplo utilizando Scapy from their website:

Aquí es otra herramienta que supervisar constantemente todas las interfaces en una máquina e imprimir toda solicitud ARP que ve, incluso en 802.11 fotogramas de un Tarjeta Wi-Fi en modo monitor. Tenga en cuenta que store = 0 parámetro para sniff() para evitar almacenar todos los paquetes en la memoria nada.

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

No es exactamente lo que estamos buscando, pero definitivamente en el camino correcto. ¡Disfrutar!

1

para sistemas basados ​​en 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) 

, aparecerá una lista de tuplas volver con Macs. scapy es una herramienta increíble, pero parece ser exagerada para este caso

1

En Linux a veces se omite la línea de comando util "arp". Una imagen de entorno incrustado de yocto linux base, por ejemplo.

Una forma alternativa y sin la función "arp" sería leer y analizar el archivo/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 
0

una manera más fácil, si en Linux:

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

obtendrá:

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