IPUtils.java
package com.ziesemer.utils.web.addressFilter.conditions;
/**
* @author Mark A. Ziesemer
* <a href="http://www.ziesemer.com."><www.ziesemer.com></a>
*/
public abstract class IPUtils{
/**
* <p>
* Checks if a given address falls into the specified subnet (defined by network address and subnet length).
* </p>
* <p>
* Both addresses must be of the same length (same number of bytes), or <code>false</code> will be returned.
* (Addresses must be padded to match.)
* </p>
* <p>
* This is essentially a convenience method for {@link #createSubnetMask(int, int)} and
* {@link #isInSubnet(byte[], byte[], byte[])}.
* </p>
*/
public static boolean isInSubnet(final byte[] network, final int subnetLength, final byte[] address){
final byte[] netmask = createSubnetMask(network.length, subnetLength);
return isInSubnet(network, netmask, address);
}
/**
* <p>
* Generates a subnet mask (netmask). The returned byte array will be of length
* <code>addressLength</code>, with the first <code>subnetLength</code> bits set to <code>1</code>.
* </p>
* @throws IllegalArgumentException If <code>subnetLength > addressLength * 8</code>.
*/
public static byte[] createSubnetMask(final int addressLength, final int subnetLength){
if(subnetLength > addressLength * 8){
throw new IllegalArgumentException("subnetLength must be <= addressLength * 8.");
}
final byte[] netmask = new byte[addressLength];
int maskPos;
for(maskPos=0; maskPos < subnetLength / 8; maskPos++){
netmask[maskPos] = (byte)0xFF;
}
if(maskPos < netmask.length){
netmask[maskPos] = (byte)(0xFF << (8 - subnetLength % 8));
}
return netmask;
}
/**
* <p>
* Checks if a given address falls into the specified subnet (defined by network address and subnet mask).
* </p>
* <p>
* All addresses must be of the same length (same number of bytes), or <code>false</code> will be returned.
* (All addresses must be padded to match.)
* </p>
*/
public static boolean isInSubnet(final byte[] network, final byte[] netmask, final byte[] address){
if(network.length != netmask.length || address.length != netmask.length){
return false;
}
for(int i=0; i < address.length; i++){
if((network[i] & netmask[i]) != (address[i] & netmask[i])){
return false;
}
}
return true;
}
/**
* <p>
* Checks if a given address falls into the range specified b the start and end addresses, inclusive.
* </p>
* <p>
* All addresses must be of the same length (same number of bytes), or <code>false</code> will be returned.
* (All addresses must be padded to match.)
* </p>
*/
public static boolean isInRange(final byte[] begin, final byte[] end, final byte[] address){
return lte(begin, address) && lte(address, end);
}
protected static boolean lte(final byte[] a, final byte[] b){
if(a.length != b.length){
return false;
}
for(int i=0; i < a.length; i++){
final byte c = a[i];
final byte d = b[i];
if(c == d){
continue;
}
if((c & 0xFF) < (d & 0xFF)){
return true;
}
return false;
}
return true;
}
}