2009-06-15 2 views
3

Я пытаюсь выполнить следующие действия в C#/.NET 2.0:Как использовать IPAddress и IPv4Mask для получения диапазона IP-адресов? .

Учитывая объект IPAddress (скажем, 192.168.127.100) и еще один объект, содержащий IP-адрес маски подсети IPv4Mask/(скажем, 255.255.248.0), Я должен уметь рассчитывать начало и конец диапазона IP-адресов.

(Да, я пытаюсь сделать для цикла через диапазон адресов в подсети.)

Теоретически, я должен быть в состоянии побитовое И на IPAddress и SubnetMask, чтобы получить IPStart , Затем я должен выполнить побитовое XOR на IPStart и инвертированную (NOT'd) SubnetMask, чтобы получить IPEnd.

Объект IPAddress предоставляет методы для вывода адреса как «long» или «byte []» (массив байтов).

Выполнение побитовой операции на длинном (поскольку оно подписано?) Приводит к недействительным результатам. И я не могу показаться, что выполнял побитовое управление в IPAddresses как массив байтов.

EDIT-1: Хорошо, зацикливание через каждый байт в массиве и выполнение побитового И, NOT и XOR (в каждой соответствующей ситуации) получает правильные результаты.

Следующая проблема, с которой я столкнулся, заключается в том, что я не могу выполнить for-loop легко после преобразования массивов byte [] в UInt32 или long. Итак, первое значение работает правильно, но приращение yint/long на один увеличивает IPaddress с 192.168.127.0 до 193.168.127.0. Кажется, что после того, как массив byte [] преобразуется в uint/long, порядок байты обращаются вспять. Таким образом, нет простого способа увеличения с IPStart до IPEnd.

У кого-нибудь есть предложения?

ответ

3

Сканирование через два байта [] массивы вместе, для каждой пары битов выполнить побитовое сравнение и поместить результат в третий байт [] массив для начала диапазона. Вы можете просканировать через массив байтов сетевого адреса [] и инвертировать каждый бит, чтобы сгенерировать маску подстановки (как вы ее называли, инвертированная маска подсети), а затем повторить процесс, как и раньше, используя маску подстановочного знака вместо маски подсети для вычисления дальность конец. Помните также, что первым значением в диапазоне является сетевой адрес подсети, а последнее значение - широковещательный адрес, поэтому эти два адреса не находятся в фактическом диапазоне адресов хоста. Вот ваш пример резюме шаг за шагом:

Address: 192.168.127.100  11000000.10101000.01111 111.01100100 
Netmask: 255.255.248.0 = 21 11111111.11111111.11111 000.00000000 
Wildcard: 0.0.7.255    00000000.00000000.00000 111.11111111 
=> 
Network: 192.168.120.0/21  11000000.10101000.01111 000.00000000 
Broadcast: 192.168.127.255  11000000.10101000.01111 111.11111111 
HostMin: 192.168.120.1   11000000.10101000.01111 000.00000001 
HostMax: 192.168.127.254  11000000.10101000.01111 111.11111110 
+0

Там нет необходимости делать это на бит, операция поразрядного на один байт (т.е. 4 операции на пару IP/маска) достаточно –

+0

Я не говорил, чтобы сделать это за бит, что потребует дополнительного шага разделения 4 байтов в массиве byte []. Может быть, я не был ясен, но я имел в виду, что для каждого байта в массиве вы выполняете побитную операцию по всему байту. – defines

1

Вы находитесь на правильном пути. Просто обрабатывайте каждый байт в массиве отдельно.

2

Вы можете использовать BitConverter, чтобы превратить эти массивы в uints.

Попробуйте это:

uint address = BitConverter.ToUInt32(IPAddress.Parse("192.168.127.100").GetAddressBytes(), 0); 
uint mask = BitConverter.ToUInt32(IPAddress.Parse("255.255.248.0").GetAddressBytes(), 0);