¿Cómo utilizar el módulo de ipaddress de Python para encontrar si subnet/ip está dentro de una subred más grande?
import ipaddress
from itertools import zip_longest
internal_subnets=[ipaddress.IPv4Network('192.168.0.0/8'),ipaddress.IPv4Network('10.0.0.0/8')]
my_sg_subnets=[ ipaddress.IPv4Network('10.0.19.1/32'),ipaddress.IPv4Network('192.168.20.0/16'), ipaddress.IPv4Network('21.0.19.1/32') ]
for big_subnet, my_ip in zip_longest(internal_subnets, my_sg_subnets):
if not my_ip.subnet_of(big_subnet):
print(f"{my_ip} is not part of {big_subnet}")
Esto falla con un None
para el último subnet en el internal_subnets
lista. Entonces, ¿cómo puedo volver a pasar por los dos primeros en la lista interna de subred?
El producto final debe ser 10.0.19.1/32 y 192.168.20.0/16 forman parte de internal_subnets
.
Por favor, avíselo.
Pregunta hecha hace 3 años, 4 meses, 29 días - Por devdynamox
3 Respuestas:
-
Por alguna razón usted escribió su código que itera a través de internal_subnets y my_sg_subnets en paralelo. Esto funciona así: en la primera iteración toma primer elemento de la primera lista, y primer elemento de la segunda lista. En segunda iteración toma segundo elemento de la primera lista y segundo elemento de la segunda lista, y así sucesivamente. En lugar de eso, tienes que hacerlo internal_subnets, y luego comprobar si cualquier elemento de my_sg_subnets es una subred. Así que el código para esto parece:
import ipaddress # Here i don't import itertools because i don't use them here internal_subnets=[ipaddress.IPv4Network('192.168.0.0/16'), ipaddress.IPv4Network('10.0.0.0/8')] # I changed network netmask from 8 to 16, because when it's set to 8 python # just throws an error (Gino Mempin posted a comment about it). I also # wrote about that below in my post. # Changing this from 8 to 16 won't affect the actual result in your case (If there was no error) my_sg_subnets=[ipaddress.IPv4Network('10.0.19.1'), ipaddress.IPv4Network('192.168.20.0'), ipaddress.IPv4Network('21.0.19.1')] for big_subnet in internal_subnets: for my_ip in my_sg_subnets: if my_ip.subnet_of(big_subnet): # Here instead of printing out everything that is not a subnet, # it prints out everything that IS a subnet print(f"{my_ip} is part of {big_subnet}")
Y funciona como se esperaba. Aquí está la salida:
192.168.20.0/32 is part of 192.168.0.0/16 10.0.19.1/32 is part of 10.0.0.0/8
Por qué tu código tiró ValueError: 192.168.0.0/8 tiene conjunto de bits de host
Sabemos que cada dirección IP_v4 es sólo 4 bytes de información, así como cada netmask IP_v4. Así que representemos 192.168.0.0 dirección y dirección 8 netmask en formato binario.
netmask: 11111111 00000000 00000000 00000000 # Netmask of 8 means that it has 8 bits in its beginning address: 11000000 10101000 00000000 00000000 ˄ ˄ ˄ You can see that this IP address has 1 in place where its netmask has only zeros. This should not happen, and this is why python raised this error
Por ejemplo, si su red tenía dirección de ip 10.0.0.0 and netmask of 8 (O más grande), funcionará, y si lo representan en binario:
netmask: 11111111 00000000 00000000 00000000 address: 00001010 00000000 00000000 00000000
Verás que todo está bien, porque la dirección no tiene nada que ver después. el final de su mampostería.
También si se establece netmask "7" para red 10.0.0.0También funcionará. Pero puede causar un problema que probablemente no necesitarás, verás que 11.0.0.0 la dirección está dentro de este 10.0.0.0 red
netmask : 11111110 00000000 00000000 00000000 address1: 00001010 00000000 00000000 00000000 # This is 10.0.0.0 addr address2: 00001011 00000000 00000000 00000000 # This is 11.0.0.0 addr ˄ This bit is different in address1 and address2, but because netmask has 0 at this position, it just doesn't matter, so address2 is inside of network with address1, because all bits that are under those 1's in the netmask are the same. Your program uses the same algorithm to check if some IP address is inside of some network
Espero que te dé una mejor comprensión de cómo funciona esto
Respondida el Dec 18, 2020 a las 04:07 - por syntaxsensei
Votos positivos: 0 | Votos negativos: 0 -
El problema que estás experimentando es debido a que la función
zip_longest
termina la iteración cuando alcanza el final de la lista más larga, y completa la iteración con el valor de rellenoNone
.Para lograr tu objetivo de verificar si las subredes de
my_sg_subnets
están dentro de las subredes más grandes deinternal_subnets
sin verse afectado por elNone
, puedes modificar el ciclofor
de esta manera:python import ipaddress internal_subnets = [ipaddress.IPv4Network('192.168.0.0/8'), ipaddress.IPv4Network('10.0.0.0/8')] my_sg_subnets = [ipaddress.IPv4Network('10.0.19.1/32'), ipaddress.IPv4Network('192.168.20.0/16'), ipaddress.IPv4Network('21.0.19.1/32')] for my_ip in my_sg_subnets: for big_subnet in internal_subnets: if my_ip.subnet_of(big_subnet): print(f"{my_ip} is part of {big_subnet}") break else: print(f"{my_ip} is not part of any internal subnet")
Con esta modificación, ahora recorremos cada subred en
my_sg_subnets
y verificamos si está dentro de cada una de las subredes más grandes eninternal_subnets
. Si una subred está dentro de alguna de las subredes más grandes, se imprime un mensaje indicando que pertenece a esa subred. Si ninguna subred está dentro de ninguna de las subredes más grandes, se imprime un mensaje indicando que no pertenece a ninguna de las subredes más grandes.Respondida el Dec 19, 2020 a las 04:08 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
El problema con el código proporcionado es que utiliza la función
zip_longest
para iterar sobre las dos listas, pero la listamy_sg_subnets
tiene un elemento menos que la listainternal_subnets
. Como resultado, cuando se alcanza el último elemento deinternal_subnets
, no hay un elemento correspondiente enmy_sg_subnets
, lo que lleva a un errorNone
.Para resolver este problema, puedes utilizar la función
cycle
de Python para crear un iterador que repita la listamy_sg_subnets
indefinidamente. Esto garantizará que siempre haya un elemento correspondiente enmy_sg_subnets
para cada elemento eninternal_subnets
.Aquí tienes el código corregido:
python import ipaddress from itertools import cycle, zip_longest internal_subnets=[ipaddress.IPv4Network('192.168.0.0/8'),ipaddress.IPv4Network('10.0.0.0/8')] my_sg_subnets=[ ipaddress.IPv4Network('10.0.19.1/32'),ipaddress.IPv4Network('192.168.20.0/16')] for big_subnet, my_ip in zip_longest(internal_subnets, cycle(my_sg_subnets)): if not my_ip.subnet_of(big_subnet): print(f"{my_ip} is not part of {big_subnet}")
Con este código corregido, el programa debería ejecutarse correctamente y producir la salida deseada:
- 0.19.1/32 is part of 10.0.0.0/8
- 168.20.0/16 is part of 192.168.0.0/8
Respondida el Dec 19, 2020 a las 04:16 - por Gemini
Votos positivos: 0 | Votos negativos: 0