将网络拆分为多个前缀的子网

时间:2016-08-10 04:29:36

标签: python python-2.7 networking

我正在使用waiting模块并尝试弄清楚如何/如何将网络拆分为不同前缀的子网。例如,取一个/ 16并将其分成X / 23s和Y / 24s。

据我所知,我们可以使用netaddr函数将网络拆分为给定前缀的X数,但只需要1个前缀。

上面的内容会从/ 16切出4/23,这很好,但是如何将剩余空间切成不同的前缀呢?

subnet

有没有办法可以实现我想用netaddr做的事情?

2 个答案:

答案 0 :(得分:4)

尝试以下

from netaddr import IPNetwork, cidr_merge, cidr_exclude

class IPSplitter(object):
    def __init__(self, base_range):
        self.avail_ranges = set((IPNetwork(base_range),))

    def get_subnet(self, prefix, count=None):
        for ip_network in self.get_available_ranges():
            subnets = list(ip_network.subnet(prefix, count=count))
            if not subnets:
                continue
            self.remove_avail_range(ip_network)
            self.avail_ranges = self.avail_ranges.union(set(cidr_exclude(ip_network, cidr_merge(subnets)[0])))
            return subnets

    def get_available_ranges(self):
        return sorted(self.avail_ranges, key=lambda x: x.prefixlen, reverse=True)

    def remove_avail_range(self, ip_network):
        self.avail_ranges.remove(ip_network)

您可以像下面一样使用它。通过更多的数学运算,您可以提高效率,例如,当单个块不满足计数时,从两个不同的块中切断子网。

In [1]: from ip_splitter import IPSplitter

In [2]: s = IPSplitter('172.24.0.0/16')

In [3]: s.get_available_ranges()
Out[3]: [IPNetwork('172.24.0.0/16')]

In [4]: s.get_subnet(23, count=4)
Out[4]: 
[IPNetwork('172.24.0.0/23'),
 IPNetwork('172.24.2.0/23'),
 IPNetwork('172.24.4.0/23'),
 IPNetwork('172.24.6.0/23')]

In [5]: s.get_available_ranges()
Out[5]: 
[IPNetwork('172.24.8.0/21'),
 IPNetwork('172.24.16.0/20'),
 IPNetwork('172.24.32.0/19'),
 IPNetwork('172.24.64.0/18'),
 IPNetwork('172.24.128.0/17')]

In [6]: s.get_subnet(28, count=10)
Out[6]: 
[IPNetwork('172.24.8.0/28'),
 IPNetwork('172.24.8.16/28'),
 IPNetwork('172.24.8.32/28'),
 IPNetwork('172.24.8.48/28'),
 IPNetwork('172.24.8.64/28'),
 IPNetwork('172.24.8.80/28'),
 IPNetwork('172.24.8.96/28'),
 IPNetwork('172.24.8.112/28'),
 IPNetwork('172.24.8.128/28'),
 IPNetwork('172.24.8.144/28')]

In [7]: s.get_available_ranges()
Out[7]: 
[IPNetwork('172.24.8.128/25'),
 IPNetwork('172.24.9.0/24'),
 IPNetwork('172.24.10.0/23'),
 IPNetwork('172.24.12.0/22'),
 IPNetwork('172.24.16.0/20'),
 IPNetwork('172.24.32.0/19'),
 IPNetwork('172.24.64.0/18'),
 IPNetwork('172.24.128.0/17')]

答案 1 :(得分:1)

在我的情况下,前缀不是完全任意的,它们总是会导致偶数分裂。例如对于/ 24我会一直要求6 / 27s和4 / 28s而在/ 23我将总是要求2 / 25s,2 / 26s,2 / 27s和4 / 28s并且我将永远从/ 24或/ 23开始,因此该方案是可以预测的。

这就是我要为/ 24而来的,同样对于/ 23:

ip = IPNetwork('10.40.72.0/24')
network28s = list(ip.subnet(28, count=16))
presentation1 = list(network28s[0:1])
presentation2 = list(network28s[1:2])
database1 = list(network28s[2:3])
database2 = list(network28s[3:4])
internetlb1 = cidr_merge(list(network28s[4:6]))
internetlb2 = cidr_merge(list(network28s[6:8]))
internet1 = cidr_merge(list(network28s[8:10]))
internet2 = cidr_merge(list(network28s[10:12]))
application1 = cidr_merge(list(network28s[12:14]))
application2 = cidr_merge(list(network28s[14:16]))

我只能这样做,因为该方案是如此可预测,并且我可以预测,这些10个子网将始终被请求,并且它们将始终具有相同的大小,唯一的差异是CIDR本身。