Given a CIDR address, e.g. 192.168.10.0/24
24
)255.255.
This is how you would do it in Java,
String[] parts = addr.split("/");
String ip = parts[0];
int prefix;
if (parts.length < 2) {
prefix = 0;
} else {
prefix = Integer.parseInt(parts[1]);
}
int mask = 0xffffffff << (32 - prefix);
System.out.println("Prefix=" + prefix);
System.out.println("Address=" + ip);
int value = mask;
byte[] bytes = new byte[]{
(byte)(value >>> 24), (byte)(value >> 16 & 0xff), (byte)(value >> 8 & 0xff), (byte)(value & 0xff) };
InetAddress netAddr = InetAddress.getByAddress(bytes);
System.out.println("Mask=" + netAddr.getHostAddress());
The algorithm is in pseudo code (actually PHP), you can translate it to java yourself.
Algoritm from here.
//$ipNetmask = "192.168.1.12/30";
list($ip, $netmask) = split( "/", $ipNetmask );
$ip_elements_decimal = split( "[.]", $ip );
$netmask_result="";
for($i=1; $i <= $netmask; $i++) {
$netmask_result .= "1";
}
for($i=$netmask+1; $i <= 32; $i++) {
$netmask_result .= "0";
}
$netmask_ip_binary_array = str_split( $netmask_result, 8 );
$netmask_ip_decimal_array = array();
foreach( $netmask_ip_binary_array as $k => $v ){
$netmask_ip_decimal_array[$k] = bindec( $v ); // "100" => 4
$network_address_array[$k] = ( $netmask_ip_decimal_array[$k] & $ip_elements_decimal[$k] );
}
$network_address = join( ".", $network_address_array );
// ------------------------------------------------
// TCP/IP NETWORK INFORMATION
// ------------------------------------------------
// IP Entered = ..................: 192.168.1.12
// CIDR = ........................: /30
// Netmask = .....................: 255.255.255.252
// Network Address = .............: 192.168.1.12
// Broadcast Address = ...........: 192.168.1.15
// Usable IP Addresses = .........: 2
// First Usable IP Address = .....: 192.168.1.13
// Last Usable IP Address = ......: 192.168.1.14
The IPAddress Java library supports both IPv4 and IPv6 in a polymorphic manner including subnets. The javadoc is available at the link. Disclaimer: I am the project manager.
All the use cases you listed are supported for both IPv4 and Ipv6 transparently.
String str = "192.168.10.0/24";
IPAddressString addrString = new IPAddressString(str);
try {
IPAddress addr = addrString.toAddress();
Integer prefix = addr.getNetworkPrefixLength(); //24
IPAddress mask = addr.getNetwork().getNetworkMask(prefix, false);//255.255.255.0
IPAddress networkAddr = addr.mask(mask); //192.168.10.0
IPAddress networkAddrOtherWay = addr.getLower().removePrefixLength(); //192.168.10.0
...
} catch(AddressStringException e) {
//e.getMessage provides validation issue
}
You can use org.springframework.security.web.util.IpAddressMatcher
from Spring Framework.
Following Yuriy's answer: To get the whole range of ip addresses, the Apache Java class SubnetUtils offers the following methods:
String[] addresses = utils.getInfo().getAllAddresses();
To download the jar containing the class go to: http://repo1.maven.org/maven2/commons-net/commons-net/3.0.1/commons-net-3.0.1.jar
The source code: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/main/java/org/apache/commons/net/util/SubnetUtils.java?view=markup
Maven id:
<groupId>commons-net<groupId> <artifactId>
commons-net<artifactId> <version>
3.0.1<version>
Here is a simple Groovy example
def cidrAddress = '192.168.10.0/24'
def cidrAddressList = cidrAddress.tokenize("\\/")
def baseIPAddress = cidrAddressList.first()
def cidrIPMask = cidrAddressList.last().toInteger()
def netMaskList = []
Integer fullOctets = cidrIPMask.intdiv(8)
fullOctets.times {netMaskList.add('255')}
def remainder = cidrIPMask % 8
netMaskList.add((256 - (2 ** (8 - remainder))).toString())
netMaskList.addAll(['0','0','0','0'])
def netMask = netMaskList.flatten().getAt(0..3).join('.')
return [cidrAddress,baseIPAddress,cidrIPMask,netMask]