Posted by: deepcani | May 17, 2011

Check if IP is within range specified in CIDR in Java

Recently I had to deal with CIDR notation. I simply needed to check if a particular IP is within the range specified by CIDR.

Here is an example, given IP range specified as 157.166.224.26/10, check if 157.166.21.21 is within this range. It seems that for .NET and C++/C folks the CIDR and IP range check come with the standard libraries. This is not the case for java, as far as I know. So, here is how I’ve done it in Java, after looking at java source code for IntetAddress, and a similar C implementation.

Let’s see what the range 157.166.224.26/10 really specifies. Here is a handy calculator which I used when playing with CIDR. So, as we can see, 157.166.224.26/10 really means you have to accept IPs from 157.128.0.0 to 157.191.255.255. The range contains 2^(32-10) IP addresses.

// Step 1. Convert IPs into ints (32 bits). 
// E.g. 157.166.224.26 becomes 10011101  10100110  11100000 00011010
int addr = (( 157 << 24 ) & 0xFF000000) 
           | (( 166 << 16 ) & 0xFF0000) 
           | (( 224 << 8 ) & 0xFF00) 
           |  ( 26 & 0xFF);

// Step 2. Get CIDR mask
int mask = (-1) << (32 - 10);

// Step 3. Find lowest IP address
int lowest = addr & mask;

// Step 4. Find highest IP address
int highest = lowest + (~mask);

Now, your IP is in the range if lowest <= IP && IP <= highest.

Hopefully, no bugs here.

Advertisements

Responses

  1. It’s really helpful for me!
    Thanks

    • Hi,

      Trying to do something similar but for ipv6 range. Need to know given an ipv6 whether or not is within a range (range is not specified using slash notation).

      How do I know ip 2001:18e8:3:171:218:8bff:fe2a:56a4 is within Range is 2001:18e8:0003:0000:0000:0000:0000:0000 – 2001:18e8:0003:ffff:ffff:ffff:ffff:ffff

      Any help greatly appreciated!!!

      • hi Lorena, since IPv6 uses 128bit addresses, and because java’s longs use 64bits, you will not be able to use code as is. Maybe you can use something like BitSet to represent addresses as a bit vector, and do the comparison on your own.

  2. Corner case: if your mask is zero bits (say, 10.0.20.111/0), you’ll get lowest = 0 and highest = -1, and no IP will be between them. The problem is that java refuses to use unsigned ints.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: