IPv6 fixes to java.net.InetAddress.

1. Make hashCode() do something that makes sense for IPv6 addresses.
2. Expand coverage of hashCode unit test.
3. Fix failing regression test for getAllByName().
4. Document that the getByName test is broken. I will fix it in a future change.
5. Expand test coverage of the isMulticastAddress test to include IPv6 and
   non-multicast addresses.

All tests now pass.

Change-Id: I6f52c7c3213dd01bf773228b1ed5d44df813f877
diff --git a/libcore/luni/src/main/java/java/net/Inet6Address.java b/libcore/luni/src/main/java/java/net/Inet6Address.java
index 0569829..5c19663 100644
--- a/libcore/luni/src/main/java/java/net/Inet6Address.java
+++ b/libcore/luni/src/main/java/java/net/Inet6Address.java
@@ -21,6 +21,7 @@
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.ObjectStreamField;
+import java.util.Arrays;
 import java.util.Enumeration;
 
 import org.apache.harmony.luni.util.Inet6Util;
@@ -409,8 +410,7 @@
      */
     @Override
     public int hashCode() {
-        /* Returns the low order int as the hash code */
-        return bytesToInt(ipaddress, 12);
+        return Arrays.hashCode(ipaddress);
     }
 
     /**
diff --git a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/net/InetAddressTest.java b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/net/InetAddressTest.java
index fa7dd26..a1c5f4f 100644
--- a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/net/InetAddressTest.java
+++ b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/net/InetAddressTest.java
@@ -228,11 +228,14 @@
             System.setSecurityManager(oldman);
         }
         
-        //Regression for HARMONY-56
-        InetAddress[] ia = InetAddress.getAllByName(null);
-        assertEquals("Assert 0: No loopback address", 1, ia.length);
-        assertTrue("Assert 1: getAllByName(null) not loopback",
-                ia[0].isLoopbackAddress());
+        // Regression for HARMONY-56
+        InetAddress[] addresses = InetAddress.getAllByName(null);
+        assertTrue("getAllByName(null): no results", addresses.length > 0);
+        for (int i = 0; i < addresses.length; i++) {
+            InetAddress address = addresses[i];
+            assertTrue("Assert 1: getAllByName(null): " + address +
+                    " is not loopback", address.isLoopbackAddress());
+        }
         
         try {
             InetAddress.getAllByName("unknown.host");
@@ -251,6 +254,11 @@
         method = "getByName",
         args = {java.lang.String.class}
     )
+    @BrokenTest("1.2.3 and 1.2 are not valid IP addresses and throw " +
+            "exceptions. These form of IP address has been the cause of " +
+            "various security vulnerabilities in the past, and all modern " +
+            "implementations refuse them. The test should be modified to " +
+            "require that they not function.")
     public void test_getByNameLjava_lang_String() throws Exception {
         // Test for method java.net.InetAddress
         // java.net.InetAddress.getByName(java.lang.String)
@@ -469,6 +477,10 @@
         }
     }
 
+    static final int TEST_IP_HASHCODE = 2130706433;
+    static final int TEST_IP6_HASHCODE = -1022939537;
+    static final int TEST_IP6_LO_HASHCODE = 1353309698;
+
     /**
      * @tests java.net.InetAddress#hashCode()
      */
@@ -478,17 +490,28 @@
         method = "hashCode",
         args = {}
     )
+    void assertHashCode(String literal, int expectedHashCode) {
+        InetAddress host = null;
+        try {
+            host = InetAddress.getByName(literal);
+        } catch(UnknownHostException e) {
+            fail("Exception during hashCode test : " + e.getMessage());
+        }
+        int hashCode = host.hashCode();
+        assertEquals("incorrect hashCode for " + host, expectedHashCode,
+                hashCode);
+    }
+
     public void test_hashCode() {
         // Test for method int java.net.InetAddress.hashCode()
-        try {
-            InetAddress host = InetAddress
-                    .getByName(Support_Configuration.InetTestAddress);
-            int hashcode = host.hashCode();
-            assertTrue("Incorrect hash returned: " + hashcode + " from host: "
-                    + host, hashcode == Support_Configuration.InetTestHashcode);
-        } catch (java.net.UnknownHostException e) {
-            fail("Exception during test : " + e.getMessage());
-        }
+        // Create InetAddresses from string literals instead of from hostnames
+        // because we are only testing hashCode, not getByName. That way the
+        // test does not depend on name resolution and we can test many
+        // different addresses, not just localhost.
+        assertHashCode(Support_Configuration.InetTestIP, TEST_IP_HASHCODE);
+        assertHashCode(Support_Configuration.InetTestIP6, TEST_IP6_HASHCODE);
+        assertHashCode(Support_Configuration.InetTestIP6LO,
+                TEST_IP6_LO_HASHCODE);
     }
 
     /**
@@ -503,9 +526,18 @@
     public void test_isMulticastAddress() {
         // Test for method boolean java.net.InetAddress.isMulticastAddress()
         try {
+            InetAddress ia1 = InetAddress.getByName("ff02::1");
+            assertTrue("isMulticastAddress returned incorrect result", ia1
+                    .isMulticastAddress());
             InetAddress ia2 = InetAddress.getByName("239.255.255.255");
             assertTrue("isMulticastAddress returned incorrect result", ia2
                     .isMulticastAddress());
+            InetAddress ia3 = InetAddress.getByName("fefb::");
+            assertFalse("isMulticastAddress returned incorrect result", ia3
+                    .isMulticastAddress());
+            InetAddress ia4 = InetAddress.getByName("10.0.0.1");
+            assertFalse("isMulticastAddress returned incorrect result", ia4
+                    .isMulticastAddress());
         } catch (Exception e) {
             fail("Exception during isMulticastAddress test : " + e.getMessage());
         }
diff --git a/libcore/support/src/test/java/tests/support/Support_Configuration.java b/libcore/support/src/test/java/tests/support/Support_Configuration.java
index 9294ae9..19af32e 100644
--- a/libcore/support/src/test/java/tests/support/Support_Configuration.java
+++ b/libcore/support/src/test/java/tests/support/Support_Configuration.java
@@ -75,8 +75,6 @@
 
     public static byte[] InetTestCaddr = { 9, 26, -56, -111 };
 
-    public static int InetTestHashcode = 2130706433;
-
     public static final String HomeAddress6 = "jcltest6.apache.org";
 
     public static String IPv6GlobalAddressJcl4 = "FE80:0000:0000:0000:020D:60FF:FE0F:A776%4"; // this
@@ -92,13 +90,6 @@
     // this allows us to check the timeouts for connect
     public static String ResolvedNotExistingHost = "9.26.194.72";
 
-    /**
-     * You can compute the hash code with the following code: try { String name =
-     * "whatever.xxx.com";
-     * System.out.println(InetAddress.getByName(name).hashCode()); } catch
-     * (UnknownHostException e) {}
-     */
-
     // BEGIN android-changed
     /**
      * An address that resolves to more than one IP address so that the
@@ -292,11 +283,6 @@
             InetTestIP2 = value;
         }
 
-        value = props.get("InetTestHashcode");
-        if (value != null) {
-            InetTestHashcode = Integer.parseInt(value);
-        }
-
         value = props.get("SpecialInetTestAddress");
         if (value != null) {
             SpecialInetTestAddress = value;