Предложение следующего доступного блока IP-сети

#python

#python

Вопрос:

Мне было интересно, есть ли хороший способ найти следующий доступный пробел для создания сетевого блока, учитывая список существующих?

Например, у меня есть эти сети в моем списке:

 [
    '10.0.0.0/24',
    '10.0.0.0/20',
    '10.10.0.0/20',
]
 

и затем кто-то приходит и спрашивает: «У вас достаточно места для 1/22 для меня?»

Я хотел бы иметь возможность предложить что-то вроде: «Вот пробел: x.x.x.x / 22» (x.x.x.x — это то, что предшествует 10.0.0.0)

или

«Вот пробел: x.x.x.x / 22» (x.x.x.x — это что-то среднее между 10.0.0.255 и 10.10.0.0)

или

«Вот пробел: x.x.x.x / 22» (x.x.x.x — это то, что появляется после 10.10.15.255)

Я был бы очень признателен за любые предложения.

Ответ №1:

ipaddress Библиотека хороша для такого варианта использования. Вы можете использовать IPv4Network класс для определения диапазонов подсетей, а IPv4Address объекты, которые он может возвращать, могут быть преобразованы в целые числа для сравнения.

Что я делаю ниже:

  1. Установите заданный список как список IPv4Network s
  2. Определите размер блока, который мы ищем
  3. Выполните итерацию по списку, вычисляя объем пространства между последовательными блоками и проверяя, подходит ли наш требуемый блок.

Вы также можете вернуть an IPv4Network со встроенной в него подсетью вместо an IPv4Address , но я оставлю это как упражнение для читателя.

 from ipaddress import IPv4Network, IPv4Address

networks = [
    IPv4Network('10.0.0.0/24')
    IPv4Network('10.0.0.0/20')
    IPv4Network('10.0.10.0/20')
]

wanted = 22
wanted_size = 2 ** (32 - wanted)  # number of addresses in a /22

space_found = None
for i in range(1, len(networks):
    previous_network_end = int(networks[i-1].network_address   int(networks[i-1].hostmask))
    next_network_start   = int(networks[i].network_address)
    free_space_size      = next_network_start - previous_network_end
    if free_space_size >= wanted_size:
        return IPv4Address(networks[i-1]   1)  # first available address
 

Комментарии:

1. Это действительно правильно. Могу ли я добавить сортировку и обрезку списка подсетей из списка перед циклом, было бы хорошей идеей. Очень признателен, парень в зеленом плаще.

2. еще 1 быстрый комментарий (не требующий от вас решения): если у меня есть этот список [IPv4Network('10.0.0.0/8'), IPv4Network('100.0.0.0/26'), IPv4Network('191.0.0.0/8'), IPv4Network('191.1.0.0/24'), IPv4Network('192.0.0.0/24')] , и я ищу пробелы / 22, я бы получил 11.0.0.0, 100.0.0.64, 191.1.1.0 в качестве следующих доступных начальных адресов разрыва. Но 100.0.0.64 и 191.1.1.0 не могут быть сетевыми адресами для / 22, поэтому вам все равно придется поработать, чтобы выяснить, можем ли мы выделить / 22 с этими пробелами. но это еще одна забавная проблема, которую нужно решить. та

3. Да, для этого вам нужно будет ввести дополнительные проверки и «ускорить» до следующей возможной /22 начальной точки. Все равно должно быть выполнимо — будет один вызов функции, когда вы определяете previous_network_end , что вам нужно будет написать