2

I need to check if an IP address is within a specific netmask, ex:

ip: 85.12.12.13
netmask: 85.12.0.0/14

I've no idea how to achieve this with java (Android), any tips ?

Pedro Lobito
  • 94,083
  • 31
  • 258
  • 268

2 Answers2

0

Convert the IP address and the mask to arrays of integers, then perform a binary and on each octet of the IP and netmask (85 & 85, 12 & 12, etc.). If the IP address is within the segment specified by the netmask, the resulting array will be equal to the netmask.

joemfb
  • 3,056
  • 20
  • 19
  • For IPv4, you could do a 'long shift', think figure out if your address fits between the First and Last address of a subnet. I think to support IPv6 you'd convert to Big Integers. – CoupFlu Apr 15 '21 at 15:19
0

I've found the solution here:

https://github.com/titpetric/wowza-geoip/blob/master/src/NetMaskLookupService.java

import java.net.InetAddress;
import java.net.UnknownHostException;

import java.util.StringTokenizer;
import java.util.Vector;

import android.app.Activity;

/** This class checks that an IP exists in a specified subnet specified via netmask.

Supported netmask formats are:

1.1.1.1/255.255.255.255
1.1.1.1/32 (CIDR-style)

@todo: IPv6 support

*/
public class iprange extends Activity
{
/** Validate that IPAddress exists in NetMask address space */
public static boolean ValidateIP(String IPAddress, String NetMask) throws UnknownHostException, Exception
{
int ip, network, netmask, cidr, tokens = 0;

// convert IP to int
if (!validateInetAddress(IPAddress)) {
return false;
}
ip = toInt(InetAddress.getByName(IPAddress));

// split network/netmask
Vector<Object> nm = new Vector<Object>();
StringTokenizer nmt = new StringTokenizer(NetMask,"/");
while (nmt.hasMoreTokens()) {
nm.add(nmt.nextToken());
tokens++;
}
// we have an ip without netmask, assume /32
if (tokens==1) {
nm.add("32");
}

// network to int
if (!validateInetAddress(nm.get(0).toString())) {
return false;
}
network = toInt(InetAddress.getByName(nm.get(0).toString()));

// generate netmask int from cidr/network notations
if (nm.get(1).toString().length() < 3) {
cidr = Integer.parseInt( nm.get(1).toString() );
if (!validateCIDR(cidr, NetMask)) {
return false;
}
netmask = 0x80000000 >> (cidr - 1); // 1st bit is sticky
} else {
if (!validateInetAddress(nm.get(1).toString())) {
return false;
}
cidr = Integer.bitCount( toInt(InetAddress.getByName(nm.get(1).toString())) );
// if we get 255.127.1.0 it's considered like 255.255.0.0 ... add netmask validation?
}
if (cidr == 32) {
return ip==network;
}
netmask = 0x80000000 >> (cidr - 1);
return ((ip & netmask) == network);
}

/** Check cidr value in bounds */
private static boolean validateCIDR(int cidr, String NetMask) throws Exception
{
if (cidr<0 || cidr>32) {
throw new Exception("CIDR value out of bounds [0..32]: "+NetMask);
}
return true;
}

/** Validate the IP address doesn't have any out of bound values */
private static boolean validateInetAddress(String IPAddress) throws Exception
{
int i = 0;
StringTokenizer tokens = new StringTokenizer(IPAddress, ".");
while (tokens.hasMoreTokens()) {
String token = tokens.nextToken().toString();
if (!Integer.toString((Integer.parseInt(token)&0xff)).equals(token)) {
throw new Exception("Can't validate IP Address: "+IPAddress);
}
i++;
}
if (i>4) {
throw new Exception("IP Address has more than 4 parts: "+IPAddress);
}
return true;
}

/** Convert InetAddress to int */
private static int toInt(InetAddress inetAddress)
{
byte[] address = inetAddress.getAddress();
int net = 0;
for (int i=0; i<address.length; i++) {
net = (net<<8) | (address[i] & 0xff);
}
return net;
}
}
Pedro Lobito
  • 94,083
  • 31
  • 258
  • 268