views:

966

answers:

3

I'm trying to accomplish the following in C#/.NET 2.0:

Given an IPAddress object (say, 192.168.127.100) and another IPAddress object containing the IPv4Mask / subnet mask (say, 255.255.248.0), I should be able calculate the start and end of the IP Address range.

(Yes, I'm trying to do a for-loop thru a range of addresses on a subnet.)

Theoretically, I should be able to bitwise AND on the IPAddress and the SubnetMask to get the IPStart. Then I should be able to perform a bitwise XOR on the IPStart and the inverted (NOT'd) SubnetMask, to get the IPEnd.

The IPAddress object provides methods to output the address as a "long" or as "byte[]" (array of bytes).

Performing the bitwise operation on the long (because it is signed?) produces invalid results. And I can't seem to perform bitwise operation on the IPAddresses as an array of bytes.

EDIT-1: Okay, looping thru each byte in the array and performing bitwise AND, NOT, and XOR (in each respective situation) gets the right results.

The next problem I am running into is that I cannot perform the for-loop easily after converting the byte[] arrays into UInt32 or long. So, the first value works properly, but incrementing the uint/long by one makes the IPaddress increase from 192.168.127.0 to 193.168.127.0 -- It seems that after the byte[] array is transformed to uint/long, the order of the bytes gets reversed. So there is no easy way to increment from IPStart to IPEnd.

Any have any suggestions?

+1  A: 

You are on the right path. Just treat each byte in the array separatedly.

Paulo Santos
A: 

You can use BitConverter to turn those arrays into uints.

Try this:

uint address = BitConverter.ToUInt32(IPAddress.Parse("192.168.127.100").GetAddressBytes(), 0);
uint mask = BitConverter.ToUInt32(IPAddress.Parse("255.255.248.0").GetAddressBytes(), 0);
Jon B
+1  A: 

Crawl through the two byte[] arrays together, for each bit pair perform the bitwise comparison and place the result into a third byte[] array for the range start. You can crawl through the network address byte[] array and invert each bit to generate the wildcard mask (as you called it, inverted subnetmask), and then repeat the process as before using the wildcard mask in place of the subnet mask to calculate the range end. Remember also that the first value in the range is the subnet network address and the last value is the broadcast address, so those two addresses are not in the actual host address range. Here is your example in a step-by-step summary:

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
Dustin Fineout
There's no need to do this per bit, a bitwise operation per byte (ie 4 operations per IP/mask pair) is enough
Sander Rijken
I was not saying to do it per bit, that would require an extra step of splitting the 4 bytes in the byte[] array up. Maybe I wasn't clear, but I meant that for each byte in the array, you are performing the bitwise operation on the entire byte.
Dustin Fineout