我正在尝试使用ipaddress(https://docs.python.org/3/library/ipaddress.html)来解决以下问题:
我的BGP聚合地址为10.76.32.0/20
我想从中减去同一路由器上的所有网络命令,以确定聚合地址是否大于定义的网络,并且还有剩余的可用网络空间。
这种情况下的网络是:
10.76.32.0/24 10.76.33.0/24 10.76.34.0/24 10.76.35.0/24 10.76.36.0/24 10.76.37.0/24 10.76.38.0/24 10.76.39.0/24 10.76.40.0/24 10.76.41.0/24 10.76.42.0/24 10.76.43.0/24 10.76.44.0/25 10.76.44.128/25 10.76.45.0/24 10.76.46.0/24 10.76.47.240/30 10.96.208.219/32
使用ipaddress.address_exclude(网络)我可以从聚合地址中减去网络,然后操作返回一个可迭代对象。
然后我可以在这个可迭代对象上创建一个for循环,看看它是否包含任何其他网络但是如果它有,我将得到另一个可迭代对象作为结果。这个过程可能会假设将列表中的列表返回到未指定的深度。
我的问题是,如果有人知道如何在列表中找到任意深度的列表结构中的所有元素。
Hunor
编辑:感谢您的回答АндрейБеньковский。我没有时间检查它但是我确实找到了一种方法来实现它而不使用netaddr的.issubset方法的递归:
def undeclared_in_aggregate(aggregate, network):
remaining = []
composite = []
for a_cidr in aggregate:
a_cidr = IPSet([a_cidr])
for n_cidr in network:
n_cidr = IPSet([n_cidr])
if n_cidr.issubset(a_cidr):
a_cidr.remove(n_cidr.iprange())
remaining = re.sub(r'IPSet\(\[|\]\)|\'', '', str(a_cidr))
remaining = remaining.split(',')
if remaining == ['']:
remaining = []
composite += remaining
return composite
这将采用列表格式的聚合地址和网络,并将差异作为新列表返回(按每个聚合地址)。
以上示例: ['10 .76.47.0 / 25','10.76.47.128 / 26','10.76.47.192 / 27','10.76.47.224 / 28','10.76.47.244 / 30','10.76.47.248 / 29'] < / p>
答案 0 :(得分:0)
你没有指出你正在使用的python(2或3)的版本所以我认为它是python3,因为你发布的链接是python3文档。您没有发布任何代码,但根据您对问题的描述,我认为您需要这样的代码:
from ipaddress import ip_network, summarize_address_range
from itertools import chain
def exclude_multiple(super_network, networks):
networks = sorted(networks, key=lambda n:n.network_address)
starts = (n.broadcast_address + 1 for n in networks)
starts = chain([super_network.network_address], starts)
ends = (n.network_address - 1 for n in networks)
ends = chain(ends, [super_network.broadcast_address])
return ((s, e) for s, e in zip(starts, ends) if s != e + 1) # s-1 != (e+1) - 1
networks = [
'10.76.32.0/24',
'10.76.33.0/24',
# more here
]
networks = map(ip_network, networks)
super_network = ip_network('10.76.32.0/20')
free_ranges = exclude_multiple(super_network, networks)
free_networks = (summarize_address_range(f, l) for f, l in free_ranges)
free_networks = list(chain.from_iterable(free_networks))
此代码不包含范围检查,因此如果networks
重叠或超出super_network
,您将从summarize_address_range
获得无效错误,但范围检查可以是添加了一些调整。