Il peut être pratique de pinger tout un réseau pour connaître les adresses IP des machines disponibles, rapidement. Voici un petit script sans prétention qui permet de pinger tout un réseau en < 5 sec, contre + 300 sec avec la méthode « à l'ancienne ».
Voici un morceau de code Python 3.4+ fonctionnant sous GNU/Linux (facilement adaptable à Windows) :
#!/usr/bin/python3
""" Ping sous stéroïdes ! """
import asyncio
from asyncio.subprocess import PIPE
import ipaddress
async def ping(ip_addr):
""" Pinger une adresse IP de manière asynchrone. """
# Lancer la commande système `ping -c1 $IP` de manière asynchrone
proc = await asyncio.create_subprocess_shell('ping -c1 ' + str(ip_addr),
stdin=PIPE,
stdout=PIPE,
stderr=PIPE)
# Récupèrer le résultat, de manière asynchrone toujours
ret = await proc.communicate()
# Et décoder le tout
ret = ret[0].decode('utf-8')
# S'il n'y a pas d'erreur, affichage de l'adresse IP
if '100% packet loss' not in ret:
print(ip_addr)
async def get_live_hosts():
""" Analyser tout un réseau de façon asynchrone. """
# Demander à l'utilisateur le réseau à analyser
# La syntaxe à utiliser : IP/masque
# Exemples :
# 192.168.0.0/24
# 192.168.0.0/255.255.255.0
network = input('Réseau [192.168.0.0/24] : ') or '192.168.0.0/24'
# Récupération de toutes les adresses IP du réseau
ip_addresses = ipaddress.ip_network(network).hosts()
# Stockage des "ping" à faire dans une liste pour traitement ultérieur
coros = []
for ip_addr in ip_addresses:
coros.append(ping(ip_addr))
# Lancer toutes les coroutines en parallèle
for routine in asyncio.as_completed(coros):
await routine
def main():
""" Point d'entrée du programme. """
# Gestion des événements asynchrones
loop = asyncio.get_event_loop()
loop.run_until_complete(get_live_hosts())
loop.close()
return 0
if __name__ == '__main__':
exit(main())
Exemple de sortie :
$ python3 ping.py
Réseau [192.168.0.0/24] :
192.168.0.10
192.168.0.11
192.168.0.12
192.168.0.254
192.168.0.48
192.168.0.36
Sources :