Pregunta

Estoy buscando una manera (con Python) de obtener el layer II dirección desde un dispositivo en mi red local. Layer III Se conocen las direcciones.

El objetivo es crear un script que sondee una base de datos de direcciones IP a intervalos regulares, asegurando que las direcciones Mac no hayan cambiado y, si lo han hecho, enviarme alertas por correo electrónico.

¿Fue útil?

Solución

Para responder a la pregunta con Python depende de la plataforma. No tengo a mano de Windows, por lo que la siguiente solución funciona en la máquina Linux lo escribí en. Un pequeño cambio en la expresión regular hará que funcione en OS.

En primer lugar, se debe hacer ping al objetivo. Eso va a colocar el blanco - siempre y cuando sea dentro de su máscara de red, que suena como en esta situación será - en la caché ARP de su sistema. Observe:

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

Sabiendo que, haces un poco de magia subproceso - de lo contrario se está escribiendo caché ARP código de comprobación de sí mismo, y no quiero 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"

Otros consejos

Hubo una pregunta similar href="https://stackoverflow.com/questions/85577/search-for-host-with-mac-address-using-python"> no respondieron demasiado largo hace en este sitio. Como se mencionó en la respuesta elegida por el autor de la pregunta de que se trate, Python no tiene una forma integrada de hacerlo. Debe bien llamar a un comando del sistema, tales como arp para obtener información ARP, o generar sus propios paquetes usando Scapy .

Editar Un ejemplo utilizando Scapy desde su página web :

  

Esta es otra herramienta que le   vigilar constantemente todas las interfaces en una   máquina e imprimir todos ARP soliciten   ve, incluso en fotogramas de un 802.11   tarjeta Wi-Fi en modo monitor. Nota la   store = 0 parámetro para sniff () para evitar   almacenar todos los paquetes en la memoria para   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 está buscando, pero definitivamente en el camino correcto. Disfrutar!

Parece que usted quiere supervisar spoofers ARP? En este caso, todo lo que necesita es arpwatch , disponible en todas las distribuciones de Linux bien abastecido cerca de usted . fuentes de descarga aquí: http://ee.lbl.gov/

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)

devolverá una lista de tuplas con macs.scapy es una herramienta increíble, pero parece excesiva para este caso.

En Linux sometimems se le pasa la línea de comandos util "arp". imagen entorno Linux incrustado Una base yocto por ejemplo.

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

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

Una solución simple usando scapy, para escanear la 192.168.0.0/24 subred es como sigue:

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

Trate de usar los netifaces que se encuentran aquí. netifaces

Actualización general para Python 3.7.Observación:la opción -n para arp no proporciona la lista de arp en sistemas Windows como se proporciona con ciertas respuestas para sistemas basados ​​en Linux.Usa la opción -a como se indica en la respuesta aquí.

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))
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top