C # Как узнать, является ли подсеть частью большей сети - PullRequest
2 голосов
/ 19 июля 2010

Я работаю с таблицей BGP в Интернете (огромный файл). Однако, суммирование маршрута может быть проблемой. Моя главная проблема заключается в том, что иногда объявляются большие порции пространства IPv4 (то есть 172.16.0.0/16), но также объявляются и более конкретные и меньшие маршруты (то есть 172.16.64.0/18). Таким образом, в таблице BGP есть две избыточные записи.

Я хотел бы найти способ получить список не избыточных IP-адресов, а только большие куски. Я подумываю о том, чтобы сравнить их все и сохранить в списке. Есть ли в C # способ узнать, является ли IP-адрес частью более широкого IP-адреса? Как в:

172.16.64.0 / 18 является частью 172.16.0.0/16 // true

Большое спасибо за вашу помощь!

alemangui

Ответы [ 2 ]

3 голосов
/ 19 июля 2010

Используйте простую математику.

IP-адрес составляет 4 байта, т.е. 32-разрядное целое число. Маска подсети точно такая же.

Учитывая это, вы можете использовать арифметику AND, чтобы определить, находится ли она внутри или вне определенной сети.

EG:

IP: 192.168.0.1      = C0 . A8 . 00 . 01
Subnet: 192.168.0.0  = C0 . A8 . 00 . 00

Is in subnet?
Thus 0xC0A80001 & 0xC0A80000 == 0xC0A80000 => true

Чтобы ответить на вопрос о том, существует ли одна сетевая работа в другой, вы можете использовать тот же подход, но сдвиньте вправо оба числа в соответствии с размером самой большой подсети.

EG:

Net A: 172.16.64.0/18 -> AC 10 40 00
Net B: 172.16.0.0/16  -> AC 10 00 00

Thus right shift both with 16 and apply previous op.

AC 10 & AC 10 == AC 10 -> true
0 голосов
/ 19 июля 2010

Рассмотрим битовые комбинации:

172.16.64.0

10101100.00010000.01000000.00000000

172.16.0.0

10101100.00010000.00000000.00000000

Обратите внимание, что установленные биты в более конкретном адресе - это установленные биты в более общем адресе плюс еще несколько. Поэтому, если мы выполним побитовое И для двух адресов, результат будет равен более общему.

Всегда ли это правильный тест? Что ж, если у нас есть два адреса, которые , а не имеют отношение удержания, AND, и биты явно дадут результат, который по крайней мере на один бит отличается от предложенного родителя, так что это тест, который мы хотим. 1008 *

Если вы знаете, какой из ваших двух адресов является предлагаемым родительским объектом, а какой - предлагаемым дочерним, то мы можем просто И биты И сравнить с предлагаемым родительским. Если они могут быть в любом порядке, И их и сравнить для обоих входов в отдельности.

Чтобы получить действительные биты, если у вас уже есть IPAddress, используйте GetAddressBytes, чтобы получить byte[], используйте BitConverter, чтобы получить unit, затем просто используйте & для побитового И.

...