0%
Gerar todos os Endereços IP de uma Rede em Python

Gerar todos os Endereços IP de uma Rede em Python

Explore vários métodos para gerar e enumerar os endereços IP de uma rede usando ipaddress, com otimização de memória e exemplos práticos de uso.

I

InSkillCoach

· min

Gerar todos os Endereços IP de uma Rede em Python

Gerar ou enumerar todos os endereços IP de uma rede é uma tarefa comum em administração de sistemas, em reconhecimento de rede e em testes de aplicações. O módulo ipaddress do Python fornece ferramentas eficientes para isso. A chave é entender a diferença entre subnets() para as sub-redes, hosts() para os endereços utilizáveis e a rede completa, além de usar geradores para evitar problemas de memória em redes grandes.

1. Enumerar os Endereços Utilizáveis com hosts()

O método hosts() retorna um gerador contendo todos os endereços IP utilizáveis de uma rede, excluindo o endereço de rede e o endereço de 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)

Converter em lista (atenção à memória!)

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. Enumerar a Rede Completa com Iteração

Para incluir o endereço de rede e o endereço de broadcast, itere diretamente sobre a rede.

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. Diferença: hosts() vs Rede Completa

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. Otimização de Memória com Geradores

Para redes grandes, use geradores e itertools.islice para limitar o número de endereços processados.

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. Dividir uma Rede em Sub-redes

O método subnets() divide uma rede em sub-redes menores.

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. Contar os Endereços

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. Exportar para Arquivo

Para processar milhões de IPs, escreva em um arquivo em vez de carregar tudo em memória.

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. Exemplo: Scanner de Rede Simples

Escaneie os endereços ativos em uma rede (observe que isso exige as permissões apropriadas).

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. Caso de Uso: Listar os Endereços por Faixa

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. Boas Práticas

  • Use geradores: não carregue milhões de IPs na memória de uma só vez.
  • hosts() vs iteração direta: use hosts() para excluir a rede e o broadcast (caso comum).
  • Atenção aos /30 e menores: um /32 tem apenas um endereço, um /31 tem dois, e hosts() retorna zero.
  • Teste primeiro em redes pequenas: antes de escanear redes /8 ou /16.
  • Respeite as leis: escaneie apenas as redes que você controla.

Conclusão

Gerar ou enumerar endereços IP de uma rede em Python é simples com ipaddress, mas é preciso ficar atento ao desempenho em redes grandes. Os geradores, subnets() e islice são seus melhores aliados para processar blocos CIDR com eficiência, sem estourar a memória. Essas técnicas são indispensáveis para a administração de sistemas, o reconhecimento de rede e os testes de infraestrutura.

InSkillCoach

Sobre InSkillCoach

Especialista em treinamento e tecnologias

Coach especializado em tecnologias avançadas e IA, apoiado pela GNeurone Inc.

Certificações:

  • AWS Certified Solutions Architect – Professional
  • Certificações Google Cloud
  • Microsoft Certified: DevOps Engineer Expert
  • Certified Kubernetes Administrator (CKA)
  • CompTIA Security+
2.0k
292

Comentários

Os comentários são alimentados pelo GitHub Discussions

Conecte-se com o GitHub para participar da discussão

Link copiado!