com.github.markusbernhardt.proxy.selector.whitelist.IpRangeFilter Maven / Gradle / Ivy
package com.github.markusbernhardt.proxy.selector.whitelist;
import java.net.InetAddress;
import java.net.URI;
import java.net.UnknownHostException;
import com.github.markusbernhardt.proxy.util.UriFilter;
/*****************************************************************************
* Filters an URI by inspecting it's IP address is in a given range. The range
* as must be defined in CIDR notation. e.g. 192.0.2.1/24,
*
* @author Markus Bernhardt, Copyright 2016
* @author Bernd Rosstauscher, Copyright 2009
****************************************************************************/
public class IpRangeFilter implements UriFilter {
private byte[] matchTo;
int numOfBits;
/*************************************************************************
* Constructor
*
* @param matchTo
* the match subnet in CIDR notation.
************************************************************************/
public IpRangeFilter(String matchTo) {
super();
String[] parts = matchTo.split("/");
if (parts.length != 2) {
throw new IllegalArgumentException("IP range is not valid:" + matchTo);
}
try {
InetAddress address = InetAddress.getByName(parts[0].trim());
this.matchTo = address.getAddress();
} catch (UnknownHostException e) {
throw new IllegalArgumentException("IP range is not valid:" + matchTo);
}
this.numOfBits = Integer.parseInt(parts[1].trim());
}
/*************************************************************************
* accept
*
* @see com.github.markusbernhardt.proxy.util.UriFilter#accept(java.net.URI)
************************************************************************/
public boolean accept(URI uri) {
if (uri == null || uri.getHost() == null) {
return false;
}
try {
InetAddress address = InetAddress.getByName(uri.getHost());
byte[] addr = address.getAddress();
// Comparing IP6 against IP4?
if (addr.length != this.matchTo.length) {
return false;
}
int bit = 0;
for (int nibble = 0; nibble < addr.length; nibble++) {
for (int nibblePos = 7; nibblePos >= 0; nibblePos--) {
int mask = 1 << nibblePos;
if ((this.matchTo[nibble] & mask) != (addr[nibble] & mask)) {
return false;
}
bit++;
if (bit >= this.numOfBits) {
return true;
}
}
}
} catch (UnknownHostException e) {
// In this case we can not get the IP do not match.
}
return false;
}
}