0%
Générer toutes les Adresses IP d'un Réseau en Python

Générer toutes les Adresses IP d'un Réseau en Python

Explorez plusieurs méthodes pour générer et énumérer les adresses IP d'un réseau en utilisant ipaddress, avec optimisation mémoire et exemples d'utilisation pratiques.

I

InSkillCoach

· min

Générer toutes les Adresses IP d’un Réseau en Python

Générer ou énumérer toutes les adresses IP d’un réseau est une tâche courante en administration système, en reconnaissance réseau et en tests d’applications. Python’s ipaddress module fournit des outils efficaces pour cela. La clé est de comprendre la différence entre subnets() pour les sous-réseaux, hosts() pour les adresses utilisables, et le réseau complet, ainsi que d’utiliser des générateurs pour éviter les problèmes de mémoire sur les grands réseaux.

1. Énumérer les Adresses Utilisables avec hosts()

La méthode hosts() renvoie un générateur contenant toutes les adresses IP utilisables d’un réseau, en excluant l’adresse réseau et l’adresse broadcast.

import ipaddress

reseau = ipaddress.ip_network("192.168.1.0/24")

# hosts() retourne un générateur (pas une liste)
print(type(reseau.hosts()))                    # <class 'generator'>

# Itérer sur tous les hôtes
for ip in reseau.hosts():
    print(ip)
# Affiche : 192.168.1.1, 192.168.1.2, ..., 192.168.1.254
# (254 adresses pour un /24)

Convertir en liste (attention à la mémoire !)

import ipaddress

reseau = ipaddress.ip_network("192.168.1.0/24")

# Convertir le générateur en liste
liste_ips = list(reseau.hosts())
print(f"Nombre d'adresses : {len(liste_ips)}")   # 254

# Accès direct à un élément
print(liste_ips[0])                             # 192.168.1.1
print(liste_ips[10])                            # 192.168.1.11

# ⚠️ WARNING : Ne pas faire cela sur un grand réseau !
# reseau_enorme = ipaddress.ip_network("10.0.0.0/8")  # 16 millions d'IPs
# liste_enorme = list(reseau_enorme.hosts())  # Consomme plusieurs Go de RAM

2. Énumérer le Réseau Complet avec Itération

Pour inclure l’adresse réseau et l’adresse broadcast, itérez directement sur le réseau.

import ipaddress

reseau = ipaddress.ip_network("192.168.1.0/24")

# Itérer sur toutes les adresses (réseau + hôtes + broadcast)
for ip in reseau:
    print(ip)
# Affiche : 192.168.1.0, 192.168.1.1, ..., 192.168.1.255
# (256 adresses pour un /24)

# Nombre total d'adresses
print(f"Nombre total : {reseau.num_addresses}")  # 256

3. Différence : hosts() vs Réseau Complet

import ipaddress

reseau = ipaddress.ip_network("10.0.0.0/30")

# hosts() : exclut l'adresse réseau et le broadcast
print("hosts():")
for ip in reseau.hosts():
    print(f"  {ip}")
# Affiche : 10.0.0.1, 10.0.0.2
# (2 adresses utilisables)

# Itération complète
print("Réseau complet:")
for ip in reseau:
    print(f"  {ip}")
# Affiche : 10.0.0.0, 10.0.0.1, 10.0.0.2, 10.0.0.3
# (4 adresses totales : réseau 0, hôtes 1-2, broadcast 3)

4. Optimisation Mémoire avec des Générateurs

Pour les grands réseaux, utilisez des générateurs et itertools.islice pour limiter le nombre d’adresses traitées.

import ipaddress
import itertools

reseau_enorme = ipaddress.ip_network("10.0.0.0/8")  # 16 millions d'IPs

# ✗ NE PAS FAIRE : cela consomme 100+ GB de RAM
# toutes_les_ips = list(reseau_enorme.hosts())

# ✓ FAIRE : utiliser un générateur et islice
print("Afficher les 10 premières adresses :")
for ip in itertools.islice(reseau_enorme.hosts(), 10):
    print(ip)
# Affiche : 10.0.0.1, 10.0.0.2, ..., 10.0.0.10

# Traiter les adresses par lots
print("\nTraiter par lots de 100 :")
for lot in iter(lambda: list(itertools.islice(reseau_enorme.hosts(), 100)), []):
    print(f"Lot de {len(lot)} adresses : {lot[0]} à {lot[-1]}")
    # Traiter chaque lot (scanner, ping, etc.)

5. Diviser un Réseau en Sous-réseaux

La méthode subnets() divise un réseau en sous-réseaux plus petits.

import ipaddress

# Réseau initial
reseau = ipaddress.ip_network("192.168.0.0/22")

# Diviser en /24 (4 sous-réseaux)
print("Sous-réseaux /24 :")
for subnet in reseau.subnets(new_prefix=24):
    print(f"  {subnet}")
# Affiche :
#   192.168.0.0/24
#   192.168.1.0/24
#   192.168.2.0/24
#   192.168.3.0/24

# Diviser en /25 (8 sous-réseaux)
print("\nSous-réseaux /25 :")
for subnet in reseau.subnets(new_prefix=25):
    print(f"  {subnet}")

6. Compter les Adresses

import ipaddress

reseau = ipaddress.ip_network("172.16.0.0/12")

# Nombre total
print(f"Total : {reseau.num_addresses}")                  # 1048576

# Nombre d'hôtes utilisables (excluant réseau et broadcast)
print(f"Hôtes utilisables : {len(list(reseau.hosts()))}")  # 1048574

# Adresses réservées
print(f"Réservées : 2 (réseau + broadcast)")

7. Exporter vers Fichier

Pour traiter des millions d’IPs, écrivez dans un fichier plutôt que de charger en mémoire.

import ipaddress

reseau = ipaddress.ip_network("10.0.0.0/16")

# Exporter en fichier texte
with open("ips.txt", "w") as f:
    for ip in reseau.hosts():
        f.write(f"{ip}\n")

# Vérifier le fichier
with open("ips.txt", "r") as f:
    nb_lignes = sum(1 for _ in f)
    print(f"Fichier contient {nb_lignes} adresses")
    # Fichier contient 65534 adresses

8. Exemple : Scanner Réseau Simple

Scannez les adresses actives dans un réseau (noter que cela nécessite les permissions appropriées).

import ipaddress
import socket
from concurrent.futures import ThreadPoolExecutor, as_completed

def ping_ip(ip, timeout=1):
    """Vérifier si une IP répond."""
    try:
        socket.create_connection((str(ip), 22), timeout=timeout)
        return True
    except (socket.timeout, socket.error):
        return False

def scanner_reseau(reseau_cidr, num_workers=10):
    """Scanner un réseau et lister les IPs actives."""
    reseau = ipaddress.ip_network(reseau_cidr, strict=False)
    actives = []
    
    with ThreadPoolExecutor(max_workers=num_workers) as executor:
        futures = {
            executor.submit(ping_ip, ip): ip 
            for ip in reseau.hosts()
        }
        
        for future in as_completed(futures):
            ip = futures[future]
            if future.result():
                actives.append(ip)
                print(f"✓ {ip} actif")
    
    return actives

# Scanner le réseau 192.168.1.0/24
# ips_actives = scanner_reseau("192.168.1.0/24")
# print(f"\nTotal actifs : {len(ips_actives)}")

# Note : remplacer socket.create_connection par un vrai ping
# pour une reconnaissance plus réaliste (ICMP)

9. Cas d’Usage : Lister les Adresses par Plage

import ipaddress

def generer_adresses_par_plages(plages):
    """
    Génère des adresses IP à partir de multiples plages CIDR.
    
    Args:
        plages (list): Liste de strings CIDR (ex: ["192.168.1.0/24", "10.0.0.0/16"])
    
    Yields:
        ipaddress.IPv4Address : adresse IP
    """
    for plage in plages:
        reseau = ipaddress.ip_network(plage, strict=False)
        for ip in reseau.hosts():
            yield ip

# Utilisation
plages_internes = [
    "192.168.0.0/16",
    "10.0.0.0/8",
    "172.16.0.0/12",
]

print("Afficher les 20 premières adresses internes :")
for i, ip in enumerate(generer_adresses_par_plages(plages_internes)):
    if i >= 20:
        break
    print(ip)

10. Bonnes Pratiques

  • Utilisez des générateurs : ne chargez pas des millions d’IPs en mémoire d’un coup.
  • hosts() vs itération directe : utilisez hosts() pour exclure le réseau et le broadcast (cas courant).
  • Attention aux /30 et plus petits : un /32 n’a qu’une adresse, un /31 en a deux, hosts() en retourne zéro.
  • Testez sur de petits réseaux d’abord : avant de scanner des /8 ou /16.
  • Respectez les lois : ne scannez que les réseaux que vous contrôlez.

Conclusion

Générer ou énumérer des adresses IP d’un réseau en Python est simple avec ipaddress, mais il faut rester conscient des performances sur les grands réseaux. Les générateurs, subnets(), et islice sont vos meilleurs alliés pour traiter efficacement les blocs CIDR sans exploser votre mémoire. Ces techniques sont indispensables pour l’administration système, la reconnaissance réseau, et les tests d’infrastructure.

InSkillCoach

À propos de InSkillCoach

Expert en formation et technologies

Coach spécialisé dans les technologies avancées et l'IA, porté par GNeurone Inc.

Certifications:

  • AWS Certified Solutions Architect – Professional
  • Certifications Google Cloud
  • Microsoft Certified: DevOps Engineer Expert
  • Certified Kubernetes Administrator (CKA)
  • CompTIA Security+
1.9k
338

Commentaires

Les commentaires sont alimentés par GitHub Discussions

Connectez-vous avec GitHub pour participer à la discussion

Lien copié !