将网络拆分为多个前缀的子网 [英] Splitting a network into subnets of multiple prefixes

查看:65
本文介绍了将网络拆分为多个前缀的子网的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 netaddr 模块并试图弄清楚如何/是否可以将网络拆分为不同前缀的子网.例如,取一个/16 并将其拆分为 X/23s 和 Y/24s.

I'm using the netaddr module and trying to figure out how/if I can split a network into subnets of varying prefixes. For example take a /16 and split it into X /23s and Y /24s.

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

From what I can tell we can use the subnet function to split a network in X number of a given prefix but it only takes 1 prefix.

上面会从/16 中切出 4 个/23,这很好,但是我如何利用剩余的空间并将其切成不同的前缀?

The above would slice out 4 /23s out of the /16 which is great, but how do I take the remaining space and slice that into a differing prefix?

ip = IPNetwork('172.24.0.0/16')
subnets = list(ip.subnet(23, count=4))

有什么方法可以让我用 netaddr 实现我想要做的事情吗?

Is there a way that I can achieve what I'm trying to do with netaddr?

推荐答案

试试下面的

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)

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

You can use it like below. With some more math you can make it more efficient,like chopping of subnets from two different blocks when count is not satisfied from a single block.

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')]

这篇关于将网络拆分为多个前缀的子网的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆