Add android.net.IpPrefix#contains()

This was originally to avoid RuntimeException in RouteInfo#matches():
    When an IPv6 prefix with a length greater than the max permitted
    for IPv4 is matched against an Inet4Address, the call to
    NetworkUtils throws RuntimeException.

Change-Id: I92e2bd19a4e7d656cf682fd27678da07e211850d
This commit is contained in:
Erik Kline
2015-04-13 15:33:34 +09:00
parent d1027f5338
commit b98afb001c
4 changed files with 49 additions and 7 deletions

View File

@@ -169,6 +169,21 @@ public final class IpPrefix implements Parcelable {
return prefixLength;
}
/**
* Determines whether the prefix contains the specified address.
*
* @param address An {@link InetAddress} to test.
* @return {@code true} if the prefix covers the given address.
*/
public boolean contains(InetAddress address) {
byte[] addrBytes = (address == null) ? null : address.getAddress();
if (addrBytes == null || addrBytes.length != this.address.length) {
return false;
}
NetworkUtils.maskRawAddress(addrBytes, prefixLength);
return Arrays.equals(this.address, addrBytes);
}
/**
* Returns a string representation of this {@code IpPrefix}.
*

View File

@@ -367,13 +367,7 @@ public final class RouteInfo implements Parcelable {
* @return {@code true} if the destination and prefix length cover the given address.
*/
public boolean matches(InetAddress destination) {
if (destination == null) return false;
// match the route destination and destination with prefix length
InetAddress dstNet = NetworkUtils.getNetworkPart(destination,
mDestination.getPrefixLength());
return mDestination.getAddress().equals(dstNet);
return mDestination.contains(destination);
}
/**

View File

@@ -29,6 +29,10 @@ import junit.framework.TestCase;
public class IpPrefixTest extends TestCase {
private static InetAddress Address(String addr) {
return InetAddress.parseNumericAddress(addr);
}
// Explicitly cast everything to byte because "error: possible loss of precision".
private static final byte[] IPV4_BYTES = { (byte) 192, (byte) 0, (byte) 2, (byte) 4};
private static final byte[] IPV6_BYTES = {
@@ -208,6 +212,34 @@ public class IpPrefixTest extends TestCase {
assertAreNotEqual(p1, p2);
}
@SmallTest
public void testContains() {
IpPrefix p = new IpPrefix("2001:db8:f00::ace:d00d/127");
assertTrue(p.contains(Address("2001:db8:f00::ace:d00c")));
assertTrue(p.contains(Address("2001:db8:f00::ace:d00d")));
assertFalse(p.contains(Address("2001:db8:f00::ace:d00e")));
assertFalse(p.contains(Address("2001:db8:f00::bad:d00d")));
assertFalse(p.contains(Address("2001:4868:4860::8888")));
assertFalse(p.contains(null));
assertFalse(p.contains(Address("8.8.8.8")));
p = new IpPrefix("192.0.2.0/23");
assertTrue(p.contains(Address("192.0.2.43")));
assertTrue(p.contains(Address("192.0.3.21")));
assertFalse(p.contains(Address("192.0.0.21")));
assertFalse(p.contains(Address("8.8.8.8")));
assertFalse(p.contains(Address("2001:4868:4860::8888")));
IpPrefix ipv6Default = new IpPrefix("::/0");
assertTrue(ipv6Default.contains(Address("2001:db8::f00")));
assertFalse(ipv6Default.contains(Address("192.0.2.1")));
IpPrefix ipv4Default = new IpPrefix("0.0.0.0/0");
assertTrue(ipv4Default.contains(Address("255.255.255.255")));
assertTrue(ipv4Default.contains(Address("192.0.2.1")));
assertFalse(ipv4Default.contains(Address("2001:db8::f00")));
}
@SmallTest
public void testHashCode() {
IpPrefix p;

View File

@@ -90,6 +90,7 @@ public class RouteInfoTest extends TestCase {
assertFalse(r.matches(Address("2001:db8:f00::ace:d00e")));
assertFalse(r.matches(Address("2001:db8:f00::bad:d00d")));
assertFalse(r.matches(Address("2001:4868:4860::8888")));
assertFalse(r.matches(Address("8.8.8.8")));
r = new PatchedRouteInfo(Prefix("192.0.2.0/23"), null, "wlan0");
assertTrue(r.matches(Address("192.0.2.43")));