简体   繁体   English

如何使用 Python 的 ipaddress 模块查找子网/ip 是否在更大的子网中?

[英]How to use Python's ipaddress module to find if subnet/ip is within a bigger subnet?

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}")

This fails with a None for the last subnet in the internal_subnets list.对于internal_subnets列表中的最后一个子网,这将失败,并显示None So, how do I iterate again through the first two in the internal_subnet list?那么,如何再次遍历 internal_subnet 列表中的前两个?

The final output should be 10.0.19.1/32 and 192.168.20.0/16 are part of internal_subnets .最终的 output 应该是 10.0.19.1/32 和 192.168.20.0/16 是internal_subnets的一部分。

Please advise.请指教。

For some reason you wrote your code that it iterates through internal_subnets and my_sg_subnets in parallel.出于某种原因,您编写的代码并行地遍历internal_subnetsmy_sg_subnets This works like this: on first iteration it grabs first element from first list, and first element from second list.这就像这样:在第一次迭代时,它从第一个列表中获取第一个元素,并从第二个列表中获取第一个元素。 On second iteration it grabs second element from first list and second element from second list, and so on.在第二次迭代中,它从第一个列表中获取第二个元素,从第二个列表中获取第二个元素,依此类推。 Instead, you need to iterate through internal_subnets , and then check if any element from my_sg_subnets is a subnet.相反,您需要遍历internal_subnets ,然后检查my_sg_subnets中的任何元素是否是子网。 So code for this looks like this:所以这个代码看起来像这样:

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}")

And it works as expected.它按预期工作。 Here's the output:这是 output:

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

Why your code threw ValueError: 192.168.0.0/8 has host bits set为什么你的代码抛出ValueError: 192.168.0.0/8 has host bits set

We know that every IP_v4 address is just 4 bytes of information, as well as every IP_v4 netmask.我们知道每个 IP_v4 地址和每个 IP_v4 网络掩码都只有 4 个字节的信息。 So let's represent 192.168.0.0 address and 8 netmask in binary format.所以让我们以二进制格式表示192.168.0.0地址和8个网络掩码。

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

For example if your network had ip address of 10.0.0.0 and netmask of 8 (Or bigger), it will work, and if represent it in binary:例如,如果您的网络的 ip 地址为10.0.0.0且网络掩码为8 (或更大),它将起作用,并且如果用二进制表示:

netmask: 11111111 00000000 00000000 00000000
address: 00001010 00000000 00000000 00000000

you'll see that everything is okay, because address has no bits set after the end of its netmask.您会看到一切正常,因为地址在其网络掩码结束后没有设置任何位。

Also if you set netmask "7" for network 10.0.0.0 , it will work as well.此外,如果您为网络10.0.0.0设置网络掩码“7”,它也可以正常工作。 But it can cause a problem that you won't probably need, you'll see that 11.0.0.0 address is inside of this 10.0.0.0 network但这可能会导致您可能不需要的问题,您会看到11.0.0.0地址在这个10.0.0.0网络内

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

Hope it'll give you better understanding of how this works希望它能让你更好地理解它是如何工作的

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM