¿Quién está en mi red?

En nuestra red casera puede venir bien conocer las IPs de los dispositivos conectados: una posibilidad es asignar direcciones fijas a los nuevos dispositivos pero es una lata asignarlas, gestionarlas y las soluciones no escalan bien en cuanto se añaden nuevos aparatitos (que es algo cada vez más frecuente).

Por eso me gustó mucho cuando descubrí Fing que era una aplicación para android (ahora se puede instalar en android, iOs, e incluso en ordenadores de escritorio) y anduve buscando la forma de emularla en mi escritorio (algo que ahora ya no sería necesario).

Las sugerencias iban en dos direcciones: nmap, y arp que no son herramientas con las que esté muy familiarizado. Sin embargo, encontré en alguna parte un aviso sobre la existencia del proyecto WiFinder, cuyo uso propuesto era generar una alerta cuando nuevos dispositivos entraban en la red. Hize mi propio fork del proyecto y estuve trabajando un rato para tratar de obtener lo que buscaba.

La solución es un programita, macfinder.py (enlace a la versión que se comenta aquí, en macfinder.py la versión que podrá evolucionar) que me ha servido para juguetear un poco con Python y estas cosas de redes. Todavía me faltaría mejorar la entrada/salida y cómo lo voy a usar, pero las ideas fundamentales están disponibles:

import nmap # import nmap.py

...
nm = nmap.PortScanner() # creates an'instance of nmap.PortScanner

Necesitaremos escanear los puertos, con la instrucción:

nm.scan(hosts='192.168.1.0/24', arguments='-n -sP -PE -T5')
# executes a ping scan

hosts_list = [(nm[x]['addresses']) for x in nm.all_hosts()]

De la lista que obtenemos vamos guardándo los datos utilizando como clave la mac (que es lo que permanece fijo en cada dispositivo), dando de alta los nuevos dispositivos encontrados cada vez:

if not ipList.has_key(addresses['mac']):
	ipList[addresses['mac']] = ("", addresses['ipv4'])

La estructura de datos es un ‘hash’ indexado por la MAC y que contiene la ip y un nombre que podemos asignar al dispositivo (igual que se hace con Fing).

Para la persistencia utilizamos pickle.
Lectura:

ipList=pickle.load(fIP)

Escritura:

fIP = open(fileName,"w")
pickle.dump(ipList,fIP)

Finalmente, algo que no tengo muy claro: Fing no necesita permisos especiales para ejecutarse (o al menos no debería, siendo una aplicación móvil en su origen) pero para que el nmap obtenga las MACs es necesario ejecutarlo con privilegios elevados (el programa debe ejecutarse con sudo y tener los permisos necesarios). Pero todo el mundo sabe que no es bueno que un programa tenga privilegios altos durante mucho tiempo, así que aproveché para aprender a hacer eso en Python. Con el consejo de: Dropping Root Permissions In Python se incluye la función drop_privileges, que justamente hace eso, con:

user_name = os.getenv("SUDO_USER")
pwnam = pwd.getpwnam(user_name)

obtenemos los datos del usuario que ha lanzado el proceso con sudo.
Con:

# Try setting the new uid/gid
os.setgid(pwnam.pw_gid)
os.setuid(pwnam.pw_uid)

Asignamos los permisos del usuario en lugar de los permisos elevados.

Esto lo hacemos en el programa, claro, cuando ya no necesitamos los privilegios altos (esto es, justo depués de utilizar el nmap).

Si hay ideas para mejorarlo, consultas, …

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s