Calculate the number of available subnets in a given network

I have the following problem when calculating the number of available subnets (or hosts) on a network. For example, the main subnet is / 24 (255.255.255.0), which contains two / 25 (255.255.255.128) or four / 26 (255.255.255.192).

So, if one node is already in use, there will only be one / 25 or only 3 times / 26. Then how do I calculate the number of available subnets. In other words, how to get the amount and type of residues. I want to execute this algorithm in PHP. enter image description here

+4
source share
1 answer

python ( , script ), , PHP. , , ( Python) , .

script : "" , BFS, pdf graphviz.

- BFS. ( "main", /24) , ( "" ) . - , "" (/25) . , "" , "". , "", "". .

.

script ( argparse):

usage: script.py [-h] -m M -t TAKEN [TAKEN ...] -o OUTPUT

optional arguments:
  -h, --help            show this help message and exit
  -m M, --m M           main subnet to check
  -t TAKEN [TAKEN ...], --taken TAKEN [TAKEN ...]
                        taken subnets
  -o OUTPUT, --output OUTPUT
                        graphviz output file name (.pdf)

script :

subnet_script.py -m 255.255.255.0/24 -t 255.255.255.192/26 -o test

:

results

- , :

script.py -m 255.255.255.0/24 -t 255.255.255.192/26 255.255.255.128/30 -o test

:

a bit more interesting results

ipaddress, queue graphviz ( python), argparse, script .

:

def get_available_subnets_set(main, taken):
    # we assume no subnets are available intially
    available = []
    q = queue.Queue()
    # add first node for expansion in the BFS process
    q.put(main)

    while q.qsize() > 0:
        subnet = q.get()
        for taken_subnet in taken:
            if taken_subnet.compare_networks(subnet) == 0:
                # found matching subnet in taken, stop expanding
                print("similar: %s and %s" % (subnet, taken_subnet))
                break
            if taken_subnet.overlaps(subnet):
                # still has overlaps somewhere in children, keep expanding
                print("overlaps: %s and %s" % (subnet, taken_subnet))
                for sub_subnet in subnet.subnets():
                    q.put(sub_subnet)
                break
        else:
            # no overlaps with taken - this subnet is entirely available
            available.append(subnet)

    return set(available)

, graphviz :

def make_subnet_graph(main, taken_subnets, available_subnets, filename):

    g = graphviz.Graph()
    q = queue.Queue()
    q.put(main)
    g.node(str(main))

    while q.qsize() > 0:
        subnet = q.get()
        for sub_subnet in subnet.subnets():
            if sub_subnet in available_subnets:
                # draw as available (green)
                g.node(str(sub_subnet), _attributes={"color": "green"})
                g.edge(str(sub_subnet), str(subnet))
                continue
            if sub_subnet in taken_subnets:
                # draw as taken (red)
                g.node(str(sub_subnet), _attributes={"color": "red"})
                g.edge(str(sub_subnet), str(subnet))
                continue

            # has mixed type subnets (taken / available) - go deeper
            g.node(str(sub_subnet))
            g.edge(str(sub_subnet), str(subnet))
            q.put(sub_subnet)

    # write file
    g.render(filename)

argparse:

#!/usr/bin/env python3.4

import ipaddress
import argparse
import queue
import graphviz


def get_available_subnets(main, taken):
    # we assume no subnets are available intially
    available = []
    q = queue.Queue()
    # add first node for expansion in the BFS process
    q.put(main)

    while q.qsize() > 0:
        subnet = q.get()
        for taken_subnet in taken:
            if taken_subnet.compare_networks(subnet) == 0:
                # found matching subnet in taken, stop expanding
                print("similar: %s and %s" % (subnet, taken_subnet))
                break
            if taken_subnet.overlaps(subnet):
                # still has overlaps somewhere in children, keep expanding
                print("overlaps: %s and %s" % (subnet, taken_subnet))
                for sub_subnet in subnet.subnets():
                    q.put(sub_subnet)
                break
        else:
            # no overlaps with taken - this subnet is entirely available
            available.append(subnet)

    return available

def make_subnet_graph(main, taken_subnets, available_subnets, filename):

    g = graphviz.Graph()
    q = queue.Queue()
    q.put(main)
    g.node(str(main))

    while q.qsize() > 0:
        subnet = q.get()
        for sub_subnet in subnet.subnets():
            if sub_subnet in available_subnets:
                # draw as available (green)
                g.node(str(sub_subnet), _attributes={"color": "green"})
                g.edge(str(sub_subnet), str(subnet))
                continue
            if sub_subnet in taken_subnets:
                # draw as taken (red)
                g.node(str(sub_subnet), _attributes={"color": "red"})
                g.edge(str(sub_subnet), str(subnet))
                continue

            # has mixed type subnets (taken / available) - go deeper
            g.node(str(sub_subnet))
            g.edge(str(sub_subnet), str(subnet))
            q.put(sub_subnet)

    # write file
    g.render(filename)


if "__main__" == __name__:
    parser = argparse.ArgumentParser()
    parser.add_argument('-m', '--m', help='main subnet to check', required=True)
    parser.add_argument('-t', '--taken', nargs='+', help='taken subnets', required=True)
    parser.add_argument('-o', '--output', help='graphviz output file name (.pdf)', required=True)
    args = parser.parse_args()

    taken = [ipaddress.IPv4Network(subnet) for subnet in args.taken]
    main = ipaddress.IPv4Network(args.m)
    available = get_available_subnets_set(main, taken)

    make_subnet_graph(main, taken, available, args.output)
+1

Source: https://habr.com/ru/post/1548466/


All Articles