Merge "Add fields used by NetworkStack to the API" am: ca2d2c268b am: 81bbdbb10f
am: 22ce4c1af7

Change-Id: I865a0298a17582c1c2d1f1eeb086979f8955ac33
diff --git a/core/java/android/net/MacAddress.java b/core/java/android/net/MacAddress.java
index c2b7d2c..77d83f5 100644
--- a/core/java/android/net/MacAddress.java
+++ b/core/java/android/net/MacAddress.java
@@ -400,6 +400,21 @@
     }
 
     /**
+     * Checks if this MAC Address matches the provided range.
+     *
+     * @param baseAddress MacAddress representing the base address to compare with.
+     * @param mask MacAddress representing the mask to use during comparison.
+     * @return true if this MAC Address matches the given range.
+     *
+     * @hide
+     */
+    public boolean matches(@NonNull MacAddress baseAddress, @NonNull MacAddress mask) {
+        Preconditions.checkNotNull(baseAddress);
+        Preconditions.checkNotNull(mask);
+        return (mAddr & mask.mAddr) == (baseAddress.mAddr & mask.mAddr);
+    }
+
+    /**
      * Create a link-local Inet6Address from the MAC address. The EUI-48 MAC address is converted
      * to an EUI-64 MAC address per RFC 4291. The resulting EUI-64 is used to construct a link-local
      * IPv6 address per RFC 4862.
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index c0aa4a6..4eab49c 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -16,9 +16,14 @@
 
 package android.net;
 
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
+
+import android.annotation.NonNull;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Build;
 import android.os.Parcel;
+import android.system.Os;
 import android.util.Log;
 import android.util.Pair;
 
@@ -573,4 +578,30 @@
         }
         return routedIPCount;
     }
+
+    private static final int[] ADDRESS_FAMILIES = new int[] {AF_INET, AF_INET6};
+
+    /**
+     * Returns true if the hostname is weakly validated.
+     * @param hostname Name of host to validate.
+     * @return True if it's a valid-ish hostname.
+     *
+     * @hide
+     */
+    public static boolean isWeaklyValidatedHostname(@NonNull String hostname) {
+        // TODO(b/34953048): Use a validation method that permits more accurate,
+        // but still inexpensive, checking of likely valid DNS hostnames.
+        final String weakHostnameRegex = "^[a-zA-Z0-9_.-]+$";
+        if (!hostname.matches(weakHostnameRegex)) {
+            return false;
+        }
+
+        for (int address_family : ADDRESS_FAMILIES) {
+            if (Os.inet_pton(address_family, hostname) != null) {
+                return false;
+            }
+        }
+
+        return true;
+    }
 }
diff --git a/tests/net/java/android/net/MacAddressTest.java b/tests/net/java/android/net/MacAddressTest.java
index 8be807d..17486e0 100644
--- a/tests/net/java/android/net/MacAddressTest.java
+++ b/tests/net/java/android/net/MacAddressTest.java
@@ -18,8 +18,8 @@
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import android.support.test.filters.SmallTest;
@@ -254,6 +254,39 @@
         }
     }
 
+    @Test
+    public void testMatches() {
+        // match 4 bytes prefix
+        assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
+                MacAddress.fromString("aa:bb:cc:dd:00:00"),
+                MacAddress.fromString("ff:ff:ff:ff:00:00")));
+
+        // match bytes 0,1,2 and 5
+        assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
+                MacAddress.fromString("aa:bb:cc:00:00:11"),
+                MacAddress.fromString("ff:ff:ff:00:00:ff")));
+
+        // match 34 bit prefix
+        assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
+                MacAddress.fromString("aa:bb:cc:dd:c0:00"),
+                MacAddress.fromString("ff:ff:ff:ff:c0:00")));
+
+        // fail to match 36 bit prefix
+        assertFalse(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
+                MacAddress.fromString("aa:bb:cc:dd:40:00"),
+                MacAddress.fromString("ff:ff:ff:ff:f0:00")));
+
+        // match all 6 bytes
+        assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
+                MacAddress.fromString("aa:bb:cc:dd:ee:11"),
+                MacAddress.fromString("ff:ff:ff:ff:ff:ff")));
+
+        // match none of 6 bytes
+        assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
+                MacAddress.fromString("00:00:00:00:00:00"),
+                MacAddress.fromString("00:00:00:00:00:00")));
+    }
+
     /**
      * Tests that link-local address generation from MAC is valid.
      */