DO NOT MERGE: backport the IPv6 NetworkInterface/multicast fixes.

This is a backport of the minimal changes from master (flan) to fix IPv6
multicasting. Specifically, it fixes NetworkInterface to report IPv6 addresses,
it fixes GenericIPMreq so we pass the interface indexes down to native code,
it replaces our old copy of harmony's MulticastSocketTest with the current
upstream version (to avoid bogus failures), and it brings back one small
"unrelated" fix to OSNetworkSystem.cpp that's necessary to prevent failures
in later parts of tests we used to fail too early to notice secondary
problems.

This passes all the (fixed) MulticastSocketTest tests, causes no regressions
in the whole net.AllTests suite, and fixes the user-submitted application
that started the investigation.

Bug: 1750581
diff --git a/libcore/Android.mk b/libcore/Android.mk
index 7de73be..2a88e14 100644
--- a/libcore/Android.mk
+++ b/libcore/Android.mk
@@ -142,7 +142,7 @@
 endif
 
 # Set up the default state.
-LOCAL_C_INCLUDES += $(JNI_H_INCLUDE)
+LOCAL_C_INCLUDES += dalvik/libcore/include $(JNI_H_INCLUDE)
 LOCAL_MODULE := $(core_magic_local_target)
 core_src_files :=
 
diff --git a/libcore/include/LocalArray.h b/libcore/include/LocalArray.h
new file mode 100644
index 0000000..74c9085
--- /dev/null
+++ b/libcore/include/LocalArray.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LOCAL_ARRAY_H_included
+#define LOCAL_ARRAY_H_included
+
+#include <cstddef>
+#include <new>
+
+/**
+ * A fixed-size array with a size hint. That number of bytes will be allocated
+ * on the stack, and used if possible, but if more bytes are requested at
+ * construction time, a buffer will be allocated on the heap (and deallocated
+ * by the destructor).
+ *
+ * The API is intended to be a compatible subset of C++0x's std::array.
+ */
+template <size_t STACK_BYTE_COUNT>
+class LocalArray {
+public:
+    /**
+     * Allocates a new fixed-size array of the given size. If this size is
+     * less than or equal to the template parameter STACK_BYTE_COUNT, an
+     * internal on-stack buffer will be used. Otherwise a heap buffer will
+     * be allocated.
+     */
+    LocalArray(size_t desiredByteCount) : mSize(desiredByteCount) {
+        if (desiredByteCount > STACK_BYTE_COUNT) {
+            mPtr = new char[mSize];
+        } else {
+            mPtr = &mOnStackBuffer[0];
+        }
+    }
+
+    /**
+     * Frees the heap-allocated buffer, if there was one.
+     */
+    ~LocalArray() {
+        if (mPtr != &mOnStackBuffer[0]) {
+            delete[] mPtr;
+        }
+    }
+
+    // Capacity.
+    size_t size() { return mSize; }
+    bool empty() { return mSize == 0; }
+
+    // Element access.
+    char& operator[](size_t n) { return mPtr[n]; }
+    const char& operator[](size_t n) const { return mPtr[n]; }
+
+private:
+    char mOnStackBuffer[STACK_BYTE_COUNT];
+    char* mPtr;
+    size_t mSize;
+};
+
+#endif // LOCAL_ARRAY_H_included
diff --git a/libcore/include/ScopedFd.h b/libcore/include/ScopedFd.h
new file mode 100644
index 0000000..30feabd
--- /dev/null
+++ b/libcore/include/ScopedFd.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SCOPED_FD_H_included
+#define SCOPED_FD_H_included
+
+#include <unistd.h>
+
+// A smart pointer that closes the given fd on going out of scope.
+// Use this when the fd is incidental to the purpose of your function,
+// but needs to be cleaned up on exit.
+class ScopedFd {
+public:
+    explicit ScopedFd(int fd) : fd(fd) {
+    }
+
+    ~ScopedFd() {
+        close(fd);
+    }
+
+    int get() const {
+        return fd;
+    }
+
+private:
+    int fd;
+};
+
+#endif  // SCOPED_FD_H_included
diff --git a/libcore/luni/src/main/java/java/net/InterfaceAddress.java b/libcore/luni/src/main/java/java/net/InterfaceAddress.java
new file mode 100644
index 0000000..7bc3936
--- /dev/null
+++ b/libcore/luni/src/main/java/java/net/InterfaceAddress.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.net;
+
+/**
+ * Identifies one of a network interface's addresses.
+ * These are passed back from the JNI behind NetworkInterface.getNetworkInterfaces.
+ * Multiple addresses for the same interface are collected together on the Java side.
+ */
+class InterfaceAddress {
+    // An IPv4 or IPv6 address.
+    final InetAddress address;
+
+    // The kernel's interface index for the network interface this address
+    // is currently assigned to. Values start at 1, because 0 means "unknown"
+    // or "any", depending on context.
+    final int index;
+
+    // The network interface's name. "lo" or "eth0", for example.
+    final String name;
+
+    InterfaceAddress(int index, String name, InetAddress address) {
+        this.index = index;
+        this.name = name;
+        this.address = address;
+    }
+}
diff --git a/libcore/luni/src/main/java/java/net/NetworkInterface.java b/libcore/luni/src/main/java/java/net/NetworkInterface.java
index 091eb9f..93a30cb 100644
--- a/libcore/luni/src/main/java/java/net/NetworkInterface.java
+++ b/libcore/luni/src/main/java/java/net/NetworkInterface.java
@@ -19,6 +19,9 @@
 
 import java.util.Arrays;
 import java.util.Enumeration;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.Vector;
 
 import org.apache.harmony.luni.util.Msg;
@@ -50,18 +53,34 @@
 
     private int hashCode;
 
-    /**
-     * This {@code native} method returns the list of network interfaces
-     * supported by the system. An array is returned which is easier to generate
-     * and which can easily be converted into the required enumeration on the
-     * java side.
-     * 
-     * @return an array of zero or more {@code NetworkInterface} objects
-     * @throws SocketException
-     *             if an error occurs when getting network interface information
-     */
-    private static native NetworkInterface[] getNetworkInterfacesImpl()
-            throws SocketException;
+    // BEGIN android-changed: we pay this extra complexity on the Java side
+    // in return for vastly simpler native code.
+    private static native InterfaceAddress[] getInterfaceAddresses() throws SocketException;
+
+    private static NetworkInterface[] getNetworkInterfacesImpl() throws SocketException {
+        Map<String, NetworkInterface> networkInterfaces = new LinkedHashMap<String, NetworkInterface>();
+        for (InterfaceAddress ia : getInterfaceAddresses()) {
+            if (ia != null) { // The array may contain harmless null elements.
+                String name = ia.name;
+                NetworkInterface ni = networkInterfaces.get(name);
+                if (ni == null) {
+                    ni = new NetworkInterface(name, name, new InetAddress[] { ia.address }, ia.index);
+                    networkInterfaces.put(name, ni);
+                } else {
+                    ni.addInterfaceAddress(ia.address);
+                }
+            }
+        }
+        return networkInterfaces.values().toArray(new NetworkInterface[networkInterfaces.size()]);
+    }
+
+    private void addInterfaceAddress(InetAddress address) {
+        InetAddress[] newAddresses = new InetAddress[addresses.length + 1];
+        System.arraycopy(addresses, 0, newAddresses, 0, addresses.length);
+        newAddresses[addresses.length] = address;
+        addresses = newAddresses;
+    }
+    // END android-changed
 
     /**
      * This constructor is used by the native method in order to construct the
@@ -334,67 +353,66 @@
      *            the object to compare with this instance.
      * @return {@code true} if the specified object is equal to this {@code
      *         NetworkInterface}, {@code false} otherwise.
-     * @see #hashCode
+     * @see #hashCode()
      */
     @Override
     public boolean equals(Object obj) {
-        // just return true if it is the exact same object
+        // Return true if it is the exact same object.
         if (obj == this) {
             return true;
         }
 
-        if (obj instanceof NetworkInterface) {
-            /*
-             * make sure that some simple checks pass. If the name is not the
-             * same then we are sure it is not the same one. We don't check the
-             * hashcode as it is generated from the name which we check
-             */
-            NetworkInterface netif = (NetworkInterface) obj;
-
-            if (netif.getIndex() != interfaceIndex) {
-                return false;
-            }
-
-            if (!(name.equals("")) && (!netif.getName().equals(name))) { //$NON-NLS-1$
-                return false;
-            }
-
-            if ((name.equals("")) && (!netif.getName().equals(displayName))) { //$NON-NLS-1$
-                return false;
-            }
-
-            // now check that the internet addresses are the same
-            Enumeration<InetAddress> netifAddresses = netif.getInetAddresses();
-            Enumeration<InetAddress> localifAddresses = getInetAddresses();
-            if ((netifAddresses == null) && (localifAddresses != null)) {
-                return false;
-            }
-
-            if ((netifAddresses == null) && (localifAddresses == null)) {
-                // neither have any addresses so they are the same
-                return true;
-            }
-
-            if (netifAddresses != null) {
-                while (netifAddresses.hasMoreElements()
-                        && localifAddresses.hasMoreElements()) {
-                    if (!(localifAddresses.nextElement()).equals(netifAddresses
-                            .nextElement())) {
-                        return false;
-                    }
-                }
-                /*
-                 * now make sure that they had the same number of internet
-                 * addresses, if not they are not the same interface
-                 */
-                if (netifAddresses.hasMoreElements()
-                        || localifAddresses.hasMoreElements()) {
-                    return false;
-                }
-            }
-            return true;
+        // Ensure it is the right type.
+        if (!(obj instanceof NetworkInterface)) {
+            return false;
         }
-        return false;
+
+        /*
+         * Make sure that some simple checks pass. If the name is not the same
+         * then we are sure it is not the same one. We don't check the hashcode
+         * as it is generated from the name which we check
+         */
+        NetworkInterface netif = (NetworkInterface) obj;
+
+        if (netif.getIndex() != interfaceIndex) {
+            return false;
+        }
+
+        if (!(name.equals("")) && (!netif.getName().equals(name))) { //$NON-NLS-1$
+            return false;
+        }
+
+        if ((name.equals("")) && (!netif.getName().equals(displayName))) { //$NON-NLS-1$
+            return false;
+        }
+
+        // Now check that the collection of internet addresses are equal.
+        Enumeration<InetAddress> netifAddresses = netif.getInetAddresses();
+        Enumeration<InetAddress> localifAddresses = getInetAddresses();
+
+        // Check for both null (same), or one null (not same).
+        if (netifAddresses == null) {
+            return localifAddresses == null;
+        }
+        if (localifAddresses == null) {
+            return false;
+        }
+
+        // Both are not null, check InetAddress elements.
+        while (netifAddresses.hasMoreElements()
+                && localifAddresses.hasMoreElements()) {
+            if (!(localifAddresses.nextElement()).equals(
+                    netifAddresses.nextElement())) {
+                return false;
+            }
+        }
+
+        /*
+         * Now make sure that they had the same number of addresses, if not they
+         * are not the same interface.
+         */
+        return !netifAddresses.hasMoreElements()
+                && !localifAddresses.hasMoreElements();
     }
 
     /**
@@ -425,6 +443,10 @@
         string.append(name);
         string.append("]["); //$NON-NLS-1$
         string.append(displayName);
+        // BEGIN android-added: the RI shows this, and it's useful for IPv6 users.
+        string.append("]["); //$NON-NLS-1$
+        string.append(interfaceIndex);
+        // END android-added
         string.append("]"); //$NON-NLS-1$
 
         /*
diff --git a/libcore/luni/src/main/java/org/apache/harmony/luni/net/GenericIPMreq.java b/libcore/luni/src/main/java/org/apache/harmony/luni/net/GenericIPMreq.java
index da300cd..8a0bd55 100644
--- a/libcore/luni/src/main/java/org/apache/harmony/luni/net/GenericIPMreq.java
+++ b/libcore/luni/src/main/java/org/apache/harmony/luni/net/GenericIPMreq.java
@@ -17,10 +17,13 @@
 
 package org.apache.harmony.luni.net;
 
+import java.lang.reflect.Field;
 import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.NetworkInterface;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.Enumeration;
 
 /**
@@ -38,9 +41,25 @@
     @SuppressWarnings("unused")
     private boolean isIPV6Address;
 
-    @SuppressWarnings("unused")
+    // BEGIN android-changed: we need interfaceIdx.
     private int interfaceIdx;
 
+    private static final Field networkInterfaceIndexField = getNetworkInterfaceField();
+    private static Field getNetworkInterfaceField() {
+        return AccessController.doPrivileged(new PrivilegedAction<Field>() {
+            public Field run() {
+                try {
+                    Field field = NetworkInterface.class.getDeclaredField("interfaceIndex");
+                    field.setAccessible(true);
+                    return field;
+                } catch (NoSuchFieldException e) {
+                    throw new AssertionError(e);
+                }
+            }
+        });
+    }
+    // END android-changed
+
     /**
      * This constructor is used to create an instance of the object
      * 
@@ -64,8 +83,13 @@
     GenericIPMreq(InetAddress addr, NetworkInterface netInterface) {
         multiaddr = addr;
         if (null != netInterface) {
-            // TODO  check if necessary
-            //interfaceIdx = netInterface.getIndex();
+            // BEGIN android-changed: we need interfaceIdx.
+            try {
+                interfaceIdx = networkInterfaceIndexField.getInt(netInterface);
+            } catch (IllegalAccessException ex) {
+                throw new AssertionError(ex);
+            }
+            // END android-changed
 
             /*
              * here we need to get the first IPV4 address as we only use it if
diff --git a/libcore/luni/src/main/native/ifaddrs-android.h b/libcore/luni/src/main/native/ifaddrs-android.h
new file mode 100644
index 0000000..e0c36bd
--- /dev/null
+++ b/libcore/luni/src/main/native/ifaddrs-android.h
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IFADDRS_ANDROID_H_included
+#define IFADDRS_ANDROID_H_included
+
+#include <cstring>
+#include <new>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#include "LocalArray.h"
+#include "ScopedFd.h"
+
+// NOTE: this in JNIHelp.h in later releases.
+const char* jniStrError(int errnum, char* buf, size_t buflen) {
+    // note: glibc has a nonstandard strerror_r that returns char* rather
+    // than POSIX's int.
+    // char *strerror_r(int errnum, char *buf, size_t n);
+    char* ret = (char*) strerror_r(errnum, buf, buflen);
+    if (((int)ret) == 0) {
+        //POSIX strerror_r, success
+        return buf;
+    } else if (((int)ret) == -1) {
+        //POSIX strerror_r, failure
+        // (Strictly, POSIX only guarantees a value other than 0. The safest
+        // way to implement this function is to use C++ and overload on the
+        // type of strerror_r to accurately distinguish GNU from POSIX. But
+        // realistic implementations will always return -1.)
+        snprintf(buf, buflen, "errno %d", errnum);
+        return buf;
+    } else {
+        //glibc strerror_r returning a string
+        return ret;
+    }
+}
+
+// NOTE: this in bionic's stdlib.h in later releases.
+#define TEMP_FAILURE_RETRY(exp) ({         \
+    typeof (exp) _rc;                      \
+    do {                                   \
+        _rc = (exp);                       \
+    } while (_rc == -1 && errno == EINTR); \
+    _rc; })
+
+// Android (bionic) doesn't have getifaddrs(3)/freeifaddrs(3).
+// We fake it here, so java_net_NetworkInterface.cpp can use that API
+// with all the non-portable code being in this file.
+
+// Source-compatible subset of the BSD struct.
+struct ifaddrs {
+    // Pointer to next struct in list, or NULL at end.
+    ifaddrs* ifa_next;
+
+    // Interface name.
+    char* ifa_name;
+
+    // Interface flags.
+    unsigned int ifa_flags;
+
+    // Interface address.
+    sockaddr* ifa_addr;
+
+    ifaddrs(ifaddrs* next)
+    : ifa_next(next), ifa_name(NULL), ifa_flags(0), ifa_addr(NULL)
+    {
+    }
+
+    ~ifaddrs() {
+        delete ifa_next;
+        delete[] ifa_name;
+        delete ifa_addr;
+    }
+
+    // Sadly, we can't keep the interface index for portability with BSD.
+    // We'll have to keep the name instead, and re-query the index when
+    // we need it later.
+    bool setNameAndFlagsByIndex(int interfaceIndex) {
+        // Get the name.
+        char buf[IFNAMSIZ];
+        char* name = if_indextoname(interfaceIndex, buf);
+        if (name == NULL) {
+            return false;
+        }
+        ifa_name = new char[strlen(name) + 1];
+        strcpy(ifa_name, name);
+
+        // Get the flags.
+        ScopedFd fd(socket(AF_INET, SOCK_DGRAM, 0));
+        if (fd.get() == -1) {
+            return false;
+        }
+        ifreq ifr;
+        memset(&ifr, 0, sizeof(ifr));
+        strcpy(ifr.ifr_name, name);
+        int rc = ioctl(fd.get(), SIOCGIFFLAGS, &ifr);
+        if (rc == -1) {
+            return false;
+        }
+        ifa_flags = ifr.ifr_flags;
+        return true;
+    }
+
+    // Netlink gives us the address family in the header, and the
+    // sockaddr_in or sockaddr_in6 bytes as the payload. We need to
+    // stitch the two bits together into the sockaddr that's part of
+    // our portable interface.
+    void setAddress(int family, void* data, size_t byteCount) {
+        sockaddr_storage* ss = new sockaddr_storage;
+        ss->ss_family = family;
+        if (family == AF_INET) {
+            void* dst = &reinterpret_cast<sockaddr_in*>(ss)->sin_addr;
+            memcpy(dst, data, byteCount);
+        } else if (family == AF_INET6) {
+            void* dst = &reinterpret_cast<sockaddr_in6*>(ss)->sin6_addr;
+            memcpy(dst, data, byteCount);
+        }
+        ifa_addr = reinterpret_cast<sockaddr*>(ss);
+    }
+};
+
+// FIXME: use iovec instead.
+struct addrReq_struct {
+    nlmsghdr netlinkHeader;
+    ifaddrmsg msg;
+};
+
+inline bool sendNetlinkMessage(int fd, const void* data, size_t byteCount) {
+    ssize_t sentByteCount = TEMP_FAILURE_RETRY(send(fd, data, byteCount, 0));
+    return (sentByteCount == static_cast<ssize_t>(byteCount));
+}
+
+inline ssize_t recvNetlinkMessage(int fd, char* buf, size_t byteCount) {
+    return TEMP_FAILURE_RETRY(recv(fd, buf, byteCount, 0));
+}
+
+// Source-compatible with the BSD function.
+inline int getifaddrs(ifaddrs** result) {
+    // Simplify cleanup for callers.
+    *result = NULL;
+
+    // Create a netlink socket.
+    ScopedFd fd(socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE));
+    if (fd.get() < 0) {
+        return -1;
+    }
+
+    // Ask for the address information.
+    addrReq_struct addrRequest;
+    memset(&addrRequest, 0, sizeof(addrRequest));
+    addrRequest.netlinkHeader.nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH;
+    addrRequest.netlinkHeader.nlmsg_type = RTM_GETADDR;
+    addrRequest.netlinkHeader.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(addrRequest)));
+    addrRequest.msg.ifa_family = AF_UNSPEC; // All families.
+    addrRequest.msg.ifa_index = 0; // All interfaces.
+    if (!sendNetlinkMessage(fd.get(), &addrRequest, addrRequest.netlinkHeader.nlmsg_len)) {
+        return -1;
+    }
+
+    // Read the responses.
+    LocalArray<0> buf(65536); // We don't necessarily have std::vector.
+    ssize_t bytesRead;
+    while ((bytesRead  = recvNetlinkMessage(fd.get(), &buf[0], buf.size())) > 0) {
+        nlmsghdr* hdr = reinterpret_cast<nlmsghdr*>(&buf[0]);
+        for (; NLMSG_OK(hdr, bytesRead); hdr = NLMSG_NEXT(hdr, bytesRead)) {
+            switch (hdr->nlmsg_type) {
+            case NLMSG_DONE:
+                return 0;
+            case NLMSG_ERROR:
+                return -1;
+            case RTM_NEWADDR:
+                {
+                    ifaddrmsg* address = reinterpret_cast<ifaddrmsg*>(NLMSG_DATA(hdr));
+                    rtattr* rta = IFA_RTA(address);
+                    size_t ifaPayloadLength = IFA_PAYLOAD(hdr);
+                    while (RTA_OK(rta, ifaPayloadLength)) {
+                        if (rta->rta_type == IFA_ADDRESS) {
+                            int family = address->ifa_family;
+                            if (family == AF_INET || family == AF_INET6) {
+                                *result = new ifaddrs(*result);
+                                if (!(*result)->setNameAndFlagsByIndex(address->ifa_index)) {
+                                    return -1;
+                                }
+                                (*result)->setAddress(family, RTA_DATA(rta), RTA_PAYLOAD(rta));
+                            }
+                        }
+                        rta = RTA_NEXT(rta, ifaPayloadLength);
+                    }
+                }
+                break;
+            }
+        }
+    }
+    // We only get here if recv fails before we see a NLMSG_DONE.
+    return -1;
+}
+
+// Source-compatible with the BSD function.
+inline void freeifaddrs(ifaddrs* addresses) {
+    delete addresses;
+}
+
+#endif  // IFADDRS_ANDROID_H_included
diff --git a/libcore/luni/src/main/native/java_net_NetworkInterface.c b/libcore/luni/src/main/native/java_net_NetworkInterface.c
deleted file mode 100644
index db6d503..0000000
--- a/libcore/luni/src/main/native/java_net_NetworkInterface.c
+++ /dev/null
@@ -1,845 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-#include "JNIHelp.h"
-#include "jni.h"
-#include "errno.h"
-
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <sys/socket.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <sys/ioctl.h>
-
-//--------------------------------------------------------------------
-// TODO copied from OSNetworkSystem. Might get into a separate .h file
-/**
- * Throws an IOException with the given message.
- */
-static void throwSocketException(JNIEnv *env, const char *message) {
-    jclass exClass = (*env)->FindClass(env, "java/net/SocketException");
-
-    if(exClass == NULL) {
-        LOGE("Unable to find class java/net/SocketException");
-    } else {
-        (*env)->ThrowNew(env, exClass, message);
-    }
-}
-
-
-/**
- * Throws a NullPointerException.
- */
-static void throwNullPointerException(JNIEnv *env) {
-    jclass exClass = (*env)->FindClass(env, "java/lang/NullPointerException");
-
-    if(exClass == NULL) {
-        LOGE("Unable to find class java/lang/NullPointerException");
-    } else {
-        (*env)->ThrowNew(env, exClass, NULL);
-    }
-}
-
-/**
- * @name Socket Errors
- * Error codes for socket operations
- *
- * @internal SOCKERR* range from -200 to -299 avoid overlap
- */
-#define SOCKERR_BADSOCKET          -200 /* generic error */
-#define SOCKERR_NOTINITIALIZED     -201 /* socket library uninitialized */
-#define SOCKERR_BADAF              -202 /* bad address family */
-#define SOCKERR_BADPROTO           -203 /* bad protocol */
-#define SOCKERR_BADTYPE            -204 /* bad type */
-#define SOCKERR_SYSTEMBUSY         -205 /* system busy handling requests */
-#define SOCKERR_SYSTEMFULL         -206 /* too many sockets */
-#define SOCKERR_NOTCONNECTED       -207 /* socket is not connected */
-#define SOCKERR_INTERRUPTED        -208 /* the call was cancelled */
-#define SOCKERR_TIMEOUT            -209 /* the operation timed out */
-#define SOCKERR_CONNRESET          -210 /* the connection was reset */
-#define SOCKERR_WOULDBLOCK         -211 /* the socket is marked as nonblocking operation would block */
-#define SOCKERR_ADDRNOTAVAIL       -212 /* address not available */
-#define SOCKERR_ADDRINUSE          -213 /* address already in use */
-#define SOCKERR_NOTBOUND           -214 /* the socket is not bound */
-#define SOCKERR_UNKNOWNSOCKET      -215 /* resolution of fileDescriptor to socket failed */
-#define SOCKERR_INVALIDTIMEOUT     -216 /* the specified timeout is invalid */
-#define SOCKERR_FDSETFULL          -217 /* Unable to create an FDSET */
-#define SOCKERR_TIMEVALFULL        -218 /* Unable to create a TIMEVAL */
-#define SOCKERR_REMSOCKSHUTDOWN    -219 /* The remote socket has shutdown gracefully */
-#define SOCKERR_NOTLISTENING       -220 /* listen() was not invoked prior to accept() */
-#define SOCKERR_NOTSTREAMSOCK      -221 /* The socket does not support connection-oriented service */
-#define SOCKERR_ALREADYBOUND       -222 /* The socket is already bound to an address */
-#define SOCKERR_NBWITHLINGER       -223 /* The socket is marked non-blocking & SO_LINGER is non-zero */
-#define SOCKERR_ISCONNECTED        -224 /* The socket is already connected */
-#define SOCKERR_NOBUFFERS          -225 /* No buffer space is available */
-#define SOCKERR_HOSTNOTFOUND       -226 /* Authoritative Answer Host not found */
-#define SOCKERR_NODATA             -227 /* Valid name, no data record of requested type */
-#define SOCKERR_BOUNDORCONN        -228 /* The socket has not been bound or is already connected */
-#define SOCKERR_OPNOTSUPP          -229 /* The socket does not support the operation */
-#define SOCKERR_OPTUNSUPP          -230 /* The socket option is not supported */
-#define SOCKERR_OPTARGSINVALID     -231 /* The socket option arguments are invalid */
-#define SOCKERR_SOCKLEVELINVALID   -232 /* The socket level is invalid */
-#define SOCKERR_TIMEOUTFAILURE     -233
-#define SOCKERR_SOCKADDRALLOCFAIL  -234 /* Unable to allocate the sockaddr structure */
-#define SOCKERR_FDSET_SIZEBAD      -235 /* The calculated maximum size of the file descriptor set is bad */
-#define SOCKERR_UNKNOWNFLAG        -236 /* The flag is unknown */
-#define SOCKERR_MSGSIZE            -237 /* The datagram was too big to fit the specified buffer & was truncated. */
-#define SOCKERR_NORECOVERY         -238 /* The operation failed with no recovery possible */
-#define SOCKERR_ARGSINVALID        -239 /* The arguments are invalid */
-#define SOCKERR_BADDESC            -240 /* The socket argument is not a valid file descriptor */
-#define SOCKERR_NOTSOCK            -241 /* The socket argument is not a socket */
-#define SOCKERR_HOSTENTALLOCFAIL   -242 /* Unable to allocate the hostent structure */
-#define SOCKERR_TIMEVALALLOCFAIL   -243 /* Unable to allocate the timeval structure */
-#define SOCKERR_LINGERALLOCFAIL    -244 /* Unable to allocate the linger structure */
-#define SOCKERR_IPMREQALLOCFAIL    -245 /* Unable to allocate the ipmreq structure */
-#define SOCKERR_FDSETALLOCFAIL     -246 /* Unable to allocate the fdset structure */
-#define SOCKERR_OPFAILED           -247
-#define SOCKERR_VALUE_NULL         -248 /* The value indexed was NULL */
-#define SOCKERR_CONNECTION_REFUSED -249 /* connection was refused */
-#define SOCKERR_ENETUNREACH        -250 /* network is not reachable */
-#define SOCKERR_EACCES             -251 /* permissions do not allow action on socket */
-
-/**
- * Answer the errorString corresponding to the errorNumber, if available.
- * This function will answer a default error string, if the errorNumber is not
- * recognized.
- *
- * This function will have to be reworked to handle internationalization properly, removing
- * the explicit strings.
- *
- * @param anErrorNum    the error code to resolve to a human readable string
- *
- * @return  a human readable error string
- */
-
-static char * netLookupErrorString(int anErrorNum) {
-    switch(anErrorNum) {
-        case SOCKERR_BADSOCKET:
-            return "Bad socket";
-        case SOCKERR_NOTINITIALIZED:
-            return "Socket library uninitialized";
-        case SOCKERR_BADAF:
-            return "Bad address family";
-        case SOCKERR_BADPROTO:
-            return "Bad protocol";
-        case SOCKERR_BADTYPE:
-            return "Bad type";
-        case SOCKERR_SYSTEMBUSY:
-            return "System busy handling requests";
-        case SOCKERR_SYSTEMFULL:
-            return "Too many sockets allocated";
-        case SOCKERR_NOTCONNECTED:
-            return "Socket is not connected";
-        case SOCKERR_INTERRUPTED:
-            return "The call was cancelled";
-        case SOCKERR_TIMEOUT:
-            return "The operation timed out";
-        case SOCKERR_CONNRESET:
-            return "The connection was reset";
-        case SOCKERR_WOULDBLOCK:
-            return "The socket is marked as nonblocking operation would block";
-        case SOCKERR_ADDRNOTAVAIL:
-            return "The address is not available";
-        case SOCKERR_ADDRINUSE:
-            return "The address is already in use";
-        case SOCKERR_NOTBOUND:
-            return "The socket is not bound";
-        case SOCKERR_UNKNOWNSOCKET:
-            return "Resolution of the FileDescriptor to socket failed";
-        case SOCKERR_INVALIDTIMEOUT:
-            return "The specified timeout is invalid";
-        case SOCKERR_FDSETFULL:
-            return "Unable to create an FDSET";
-        case SOCKERR_TIMEVALFULL:
-            return "Unable to create a TIMEVAL";
-        case SOCKERR_REMSOCKSHUTDOWN:
-            return "The remote socket has shutdown gracefully";
-        case SOCKERR_NOTLISTENING:
-            return "Listen() was not invoked prior to accept()";
-        case SOCKERR_NOTSTREAMSOCK:
-            return "The socket does not support connection-oriented service";
-        case SOCKERR_ALREADYBOUND:
-            return "The socket is already bound to an address";
-        case SOCKERR_NBWITHLINGER:
-            return "The socket is marked non-blocking & SO_LINGER is non-zero";
-        case SOCKERR_ISCONNECTED:
-            return "The socket is already connected";
-        case SOCKERR_NOBUFFERS:
-            return "No buffer space is available";
-        case SOCKERR_HOSTNOTFOUND:
-            return "Authoritative Answer Host not found";
-        case SOCKERR_NODATA:
-            return "Valid name, no data record of requested type";
-        case SOCKERR_BOUNDORCONN:
-            return "The socket has not been bound or is already connected";
-        case SOCKERR_OPNOTSUPP:
-            return "The socket does not support the operation";
-        case SOCKERR_OPTUNSUPP:
-            return "The socket option is not supported";
-        case SOCKERR_OPTARGSINVALID:
-            return "The socket option arguments are invalid";
-        case SOCKERR_SOCKLEVELINVALID:
-            return "The socket level is invalid";
-        case SOCKERR_TIMEOUTFAILURE:
-            return "The timeout operation failed";
-        case SOCKERR_SOCKADDRALLOCFAIL:
-            return "Failed to allocate address structure";
-        case SOCKERR_FDSET_SIZEBAD:
-            return "The calculated maximum size of the file descriptor set is bad";
-        case SOCKERR_UNKNOWNFLAG:
-            return "The flag is unknown";
-        case SOCKERR_MSGSIZE:
-            return "The datagram was too big to fit the specified buffer, so truncated";
-        case SOCKERR_NORECOVERY:
-            return "The operation failed with no recovery possible";
-        case SOCKERR_ARGSINVALID:
-            return "The arguments are invalid";
-        case SOCKERR_BADDESC:
-            return "The socket argument is not a valid file descriptor";
-        case SOCKERR_NOTSOCK:
-            return "The socket argument is not a socket";
-        case SOCKERR_HOSTENTALLOCFAIL:
-            return "Unable to allocate the hostent structure";
-        case SOCKERR_TIMEVALALLOCFAIL:
-            return "Unable to allocate the timeval structure";
-        case SOCKERR_LINGERALLOCFAIL:
-            return "Unable to allocate the linger structure";
-        case SOCKERR_IPMREQALLOCFAIL:
-            return "Unable to allocate the ipmreq structure";
-        case SOCKERR_FDSETALLOCFAIL:
-            return "Unable to allocate the fdset structure";
-        case SOCKERR_CONNECTION_REFUSED:
-            return "Connection refused";
-
-        default:
-            return "unkown error";
-    }
-}
-
-/**
- * Converts a native address structure to a 4-byte array. Throws a
- * NullPointerException or an IOException in case of error. This is
- * signaled by a return value of -1. The normal return value is 0.
- */
-static int structInToJavaAddress(
-        JNIEnv *env, struct in_addr *address, jbyteArray java_address) {
-
-    if(java_address == NULL) {
-        throwNullPointerException(env);
-        return -1;
-    }
-
-    if((*env)->GetArrayLength(env, java_address) != sizeof(address->s_addr)) {
-        jniThrowIOException(env, errno);
-        return -1;
-    }
-
-    jbyte *java_address_bytes;
-
-    java_address_bytes = (*env)->GetByteArrayElements(env, java_address, NULL);
-
-    memcpy(java_address_bytes, &(address->s_addr), sizeof(address->s_addr));
-
-    (*env)->ReleaseByteArrayElements(env, java_address, java_address_bytes, 0);
-
-    return 0;
-}
-
-static jobject structInToInetAddress(JNIEnv *env, struct in_addr *address) {
-    jbyteArray bytes;
-    int success;
-
-    bytes = (*env)->NewByteArray(env, 4);
-
-    if(bytes == NULL) {
-        return NULL;
-    }
-
-    success = structInToJavaAddress(env, address, bytes);
-
-    if(success < 0) {
-        return NULL;
-    }
-
-    jclass iaddrclass = (*env)->FindClass(env, "java/net/InetAddress");
-
-    if(iaddrclass == NULL) {
-        LOGE("Can't find java/net/InetAddress");
-        jniThrowException(env, "java/lang/ClassNotFoundException", "java.net.InetAddress");
-        return NULL;
-    }
-
-    jmethodID iaddrgetbyaddress = (*env)->GetStaticMethodID(env, iaddrclass, "getByAddress", "([B)Ljava/net/InetAddress;");
-
-    if(iaddrgetbyaddress == NULL) {
-        LOGE("Can't find method InetAddress.getByAddress(byte[] val)");
-        jniThrowException(env, "java/lang/NoSuchMethodError", "InetAddress.getByAddress(byte[] val)");
-        return NULL;
-    }
-
-    return (*env)->CallStaticObjectMethod(env, iaddrclass, iaddrgetbyaddress, bytes);
-}
-//--------------------------------------------------------------------
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/* structure for returning either and IPV4 or IPV6 ip address */
-typedef struct ipAddress_struct {
-    union {
-        char bytes[sizeof(struct in_addr)];
-        struct in_addr inAddr;
-    } addr;
-    unsigned int length;
-    unsigned int  scope;
-} ipAddress_struct;
-
-/* structure for returning network interface information */
-typedef struct NetworkInterface_struct {
-    char *name;
-    char *displayName;
-    unsigned int  numberAddresses;
-    unsigned int  index;
-    struct ipAddress_struct *addresses;
-} NetworkInterface_struct;
-
-/* array of network interface structures */
-typedef struct NetworkInterfaceArray_struct {
-    unsigned int  length;
-    struct NetworkInterface_struct *elements;
-} NetworkInterfaceArray_struct;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/**
- * Frees the memory allocated for the hyNetworkInterface_struct array passed in
- *
- * @param[in] portLibrary The port library.
- * @param[in] handle Pointer to array of network interface structures to be freed
- *
- * @return 0 on success
-*/
-int sock_free_network_interface_struct (struct NetworkInterfaceArray_struct *array) {
-    unsigned int i = 0;
-
-    if((array != NULL) && (array->elements != NULL)) {
-
-        /* free the allocated memory in each of the structures */
-        for(i = 0; i < array->length; i++) {
-
-            /* free the name, displayName and addresses */
-            if(array->elements[i].name != NULL) {
-                free(array->elements[i].name);
-            }
-
-            if(array->elements[i].displayName != NULL) {
-                free(array->elements[i].displayName);
-            }
-
-            if(array->elements[i].addresses != NULL) {
-                free(array->elements[i].addresses);
-            }
-        }
-
-        /* now free the array itself */
-        free(array->elements);
-    }
-
-    return 0;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/**
- * Queries and returns the information for the network interfaces that are currently active within the system.
- * Applications are responsible for freeing the memory returned via the handle.
- *
- * @param[in] portLibrary The port library.
- * @param[in,out] array Pointer to structure with array of network interface entries
- * @param[in] boolean which indicates if we should prefer the IPv4 stack or not
- *
- * @return The number of elements in handle on success, negatvie portable error code on failure.
-                               -WSANO_RECOVERY if system calls required to get the info fail, -WSAENOBUFS if memory allocation fails
- * @note A return value of 0 indicates no interfaces exist
-*/
-int sockGetNetworkInterfaces(struct NetworkInterfaceArray_struct * array) {
-
-    struct NetworkInterface_struct *interfaces = NULL;
-    unsigned int nameLength = 0;
-    unsigned int currentAdapterIndex = 0;
-    unsigned int counter = 0;
-    unsigned int result = 0;
-    unsigned int numAddresses = 0;
-    unsigned int currentIPAddressIndex = 0;
-    unsigned int numAdapters = 0;
-    int err = 0;
-
-    struct ifconf ifc;
-    int len = 32 * sizeof(struct ifreq);
-    int socketP = 0;
-    unsigned int totalInterfaces = 0;
-    struct ifreq reqCopy;
-    unsigned int counter2 = 0;
-    char *lastName = NULL;
-
-    int ifconfCommand = SIOCGIFCONF;
-
-    /* this method is not guarranteed to return the IPV6 addresses.  Code is include so that if the platform returns IPV6 addresses
-       in reply to the SIOCGIFCONF they will be included.  Howerver, it is not guarranteed or even expected that many platforms will
-       include the IPV6 addresses.  For this reason there are other specific implementations that will return the IPV6 addresses */
-    /* first get the list of interfaces.  We do not know how long the buffer needs to be so we try with one that allows for
-       32 interfaces.  If this turns out not to be big enough then we expand the buffer to be able to support another
-       32 interfaces and try again.  We do this until the result indicates that the result fit into the buffer provided */
-    /* we need  socket to do the ioctl so create one */
-    socketP = socket(PF_INET, SOCK_DGRAM, 0);
-    if(socketP < 0) {
-        return socketP;
-    }
-    for(;;) {
-        char *data = (char *)malloc(len * sizeof(char));
-        if(data == NULL) {
-          close(socketP);
-          return SOCKERR_NOBUFFERS;
-        }
-        ifc.ifc_len = len;
-        ifc.ifc_buf = data;
-        errno = 0;
-        if(ioctl(socketP, ifconfCommand, &ifc) != 0) {
-          err = errno;
-          free(ifc.ifc_buf);
-          close(socketP);
-          return SOCKERR_NORECOVERY;
-        }
-        if(ifc.ifc_len < len)
-        break;
-        /* the returned data was likely truncated, expand the buffer and try again */
-        free(ifc.ifc_buf);
-        len += 32 * sizeof(struct ifreq);
-    }
-
-    /* get the number of distinct interfaces */
-    if(ifc.ifc_len != 0) {
-        totalInterfaces = ifc.ifc_len / sizeof(struct ifreq);
-    }
-    lastName = NULL;
-    for(counter = 0; counter < totalInterfaces; counter++) {
-        if((NULL == lastName) || (strncmp(lastName, ifc.ifc_req[counter].ifr_name, IFNAMSIZ) != 0)) {
-            /* make sure the interface is up */
-            reqCopy = ifc.ifc_req[counter];
-            ioctl(socketP, SIOCGIFFLAGS, &reqCopy);
-            if((reqCopy.ifr_flags) & (IFF_UP == IFF_UP)) {
-                numAdapters++;
-            }
-        }
-        lastName = ifc.ifc_req[counter].ifr_name;
-    }
-
-    /* now allocate the space for the hyNetworkInterface structs and fill it in */
-    interfaces = malloc(numAdapters * sizeof(NetworkInterface_struct));
-    if(NULL == interfaces) {
-        free(ifc.ifc_buf);
-        close(socketP);
-        return SOCKERR_NOBUFFERS;
-    }
-
-    /* initialize the structure so that we can free allocated if a failure occurs */
-    for(counter = 0; counter < numAdapters; counter++) {
-        interfaces[counter].name = NULL;
-        interfaces[counter].displayName = NULL;
-        interfaces[counter].addresses = NULL;
-    }
-
-    /* set up the return stucture */
-    array->elements = interfaces;
-    array->length = numAdapters;
-    lastName = NULL;
-    for(counter = 0; counter < totalInterfaces; counter++) {
-        /* make sure the interface is still up */
-        reqCopy = ifc.ifc_req[counter];
-        ioctl(socketP, SIOCGIFFLAGS, &reqCopy);
-        if((reqCopy.ifr_flags) & (IFF_UP == IFF_UP)) {
-            /* since this function can return multiple entries for the same name, only do it for the first one with any given name */
-            if((NULL == lastName) || (strncmp(lastName, ifc.ifc_req[counter].ifr_name, IFNAMSIZ) != 0)) {
-
-                /* get the index for the interface */
-                interfaces[currentAdapterIndex].index =
-                        ifc.ifc_req[counter].ifr_ifindex;
-                /* get the name and display name for the adapter */
-                /* there only seems to be one name so use it for both the name and the display name */
-                nameLength = strlen(ifc.ifc_req[counter].ifr_name);
-                interfaces[currentAdapterIndex].name = malloc(nameLength + 1);
-
-                if(NULL == interfaces[currentAdapterIndex].name) {
-                    free(ifc.ifc_buf);
-                    sock_free_network_interface_struct(array);
-                    close(socketP);
-                    return SOCKERR_NOBUFFERS;
-                }
-                strncpy(interfaces[currentAdapterIndex].name, ifc.ifc_req[counter].ifr_name, nameLength);
-                interfaces[currentAdapterIndex].name[nameLength] = 0;
-                nameLength = strlen(ifc.ifc_req[counter].ifr_name);
-                interfaces[currentAdapterIndex].displayName = malloc(nameLength + 1);
-                if(NULL == interfaces[currentAdapterIndex].displayName) {
-                    free(ifc.ifc_buf);
-                    sock_free_network_interface_struct(array);
-                    close(socketP);
-                    return SOCKERR_NOBUFFERS;
-                }
-                strncpy(interfaces[currentAdapterIndex].displayName, ifc.ifc_req[counter].ifr_name, nameLength);
-                interfaces[currentAdapterIndex].displayName[nameLength] = 0;
-
-                /* check how many addresses/aliases this adapter has.  aliases show up as adaptors with the same name */
-                numAddresses = 0;
-                for(counter2 = counter; counter2 < totalInterfaces; counter2++) {
-                    if(strncmp(ifc.ifc_req[counter].ifr_name, ifc.ifc_req[counter2].ifr_name, IFNAMSIZ) == 0) {
-                        if(ifc.ifc_req[counter2].ifr_addr.sa_family == AF_INET) {
-                            numAddresses++;
-                        }
-                    } else {
-                      break;
-                    }
-                }
-
-                /* allocate space for the addresses */
-                interfaces[currentAdapterIndex].numberAddresses = numAddresses;
-                interfaces[currentAdapterIndex].addresses = malloc(numAddresses * sizeof(ipAddress_struct));
-                if(NULL == interfaces[currentAdapterIndex].addresses) {
-                    free(ifc.ifc_buf);
-                    sock_free_network_interface_struct(array);
-                    close(socketP);
-                    return SOCKERR_NOBUFFERS;
-                }
-
-                /* now get the addresses */
-                currentIPAddressIndex = 0;
-                lastName = ifc.ifc_req[counter].ifr_name;
-
-                for(;;) {
-                    if(ifc.ifc_req[counter].ifr_addr.sa_family == AF_INET) {
-                        interfaces[currentAdapterIndex].addresses[currentIPAddressIndex].addr.inAddr.s_addr = ((struct sockaddr_in *) (&ifc.ifc_req[counter].ifr_addr))->sin_addr.s_addr;
-                        interfaces[currentAdapterIndex].addresses[currentIPAddressIndex].length = sizeof(struct in_addr);
-                        interfaces[currentAdapterIndex].addresses[currentIPAddressIndex].scope = 0;
-                        currentIPAddressIndex++;
-                    }
-
-                    /* we mean to increment the outside counter here as we want to skip the next entry as it is for the same interface
-                                          as we are currently working on */
-                    if((counter + 1 < totalInterfaces) && (strncmp(ifc.ifc_req[counter + 1].ifr_name, lastName, IFNAMSIZ) == 0)) {
-                        counter++;
-                    } else {
-                        break;
-                    }
-
-                }
-                currentAdapterIndex++;
-            }
-        }
-    }          /* for over all interfaces */
-    /* now an interface might have been taken down since we first counted them */
-    array->length = currentAdapterIndex;
-    /* free the memory now that we are done with it */
-    free(ifc.ifc_buf);
-    close(socketP);
-
-    return 0;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/**
- * Answer an array of NetworkInterface objects.  One for each network interface within the system
- *
- * @param      env     pointer to the JNI library
- * @param      clazz   the class of the object invoking the JNI function
- *
- * @return                     an array of NetworkInterface objects of length 0 or more
- */
-
-static jobjectArray getNetworkInterfacesImpl(JNIEnv * env, jclass clazz) {
-
-    /* variables to store network interfac edata returned by call to port library */
-    struct NetworkInterfaceArray_struct networkInterfaceArray;
-    int result = 0;
-
-    /* variables for class and method objects needed to create bridge to java */
-    jclass networkInterfaceClass = NULL;
-    jclass inetAddressClass = NULL;
-    jclass utilClass = NULL;
-    jmethodID methodID = NULL;
-    jmethodID utilMid = NULL;
-
-    /* JNI objects used to return values from native call */
-    jstring name = NULL;
-    jstring displayName = NULL;
-    jobjectArray addresses = NULL;
-    jobjectArray networkInterfaces = NULL;
-    jbyteArray bytearray = NULL;
-
-    /* jobjects used to build the object arrays returned */
-    jobject currentInterface = NULL;
-    jobject element = NULL;
-
-    /* misc variables needed for looping and determining inetAddress info */
-    unsigned int i = 0;
-    unsigned int j = 0;
-    unsigned int nameLength = 0;
-
-    /* get the classes and methods that we need for later calls */
-    networkInterfaceClass = (*env)->FindClass(env, "java/net/NetworkInterface");
-    if(networkInterfaceClass == NULL) {
-        throwSocketException(env, netLookupErrorString(SOCKERR_NORECOVERY));
-        return NULL;
-    }
-
-    inetAddressClass = (*env)->FindClass(env, "java/net/InetAddress");
-    if(inetAddressClass == NULL) {
-        throwSocketException(env, netLookupErrorString(SOCKERR_NORECOVERY));
-        return NULL;
-    }
-
-    methodID = (*env)->GetMethodID(env, networkInterfaceClass, "<init>",
-            "(Ljava/lang/String;Ljava/lang/String;[Ljava/net/InetAddress;I)V");
-    if(methodID == NULL) {
-        throwSocketException(env, netLookupErrorString(SOCKERR_NORECOVERY));
-        return NULL;
-    }
-
-    utilClass = (*env)->FindClass(env, "org/apache/harmony/luni/util/Util");
-    if(!utilClass) {
-        return NULL;
-    }
-
-    utilMid = ((*env)->GetStaticMethodID(env, utilClass, "toString",
-            "([BII)Ljava/lang/String;"));
-    if(!utilMid) {
-        return NULL;
-    }
-
-    result = sockGetNetworkInterfaces(&networkInterfaceArray);
-
-    if(result < 0) {
-        /* this means an error occured.  The value returned is the socket error that should be returned */
-        throwSocketException(env, netLookupErrorString(result));
-        return NULL;
-    }
-
-    /* now loop through the interfaces and extract the information to be returned */
-    for(j = 0; j < networkInterfaceArray.length; j++) {
-        /* set the name and display name and reset the addresses object array */
-        addresses = NULL;
-        name = NULL;
-        displayName = NULL;
-
-        if(networkInterfaceArray.elements[j].name != NULL) {
-            nameLength = strlen(networkInterfaceArray.elements[j].name);
-            bytearray = (*env)->NewByteArray(env, nameLength);
-            if(bytearray == NULL) {
-                /* NewByteArray should have thrown an exception */
-                return NULL;
-            }
-            (*env)->SetByteArrayRegion(env, bytearray, (jint) 0, nameLength,
-                    (jbyte *)networkInterfaceArray.elements[j].name);
-            name = (*env)->CallStaticObjectMethod(env, utilClass, utilMid,
-                    bytearray, (jint) 0, nameLength);
-            if((*env)->ExceptionCheck(env)) {
-                return NULL;
-            }
-        }
-
-        if(networkInterfaceArray.elements[j].displayName != NULL) {
-            nameLength = strlen(networkInterfaceArray.elements[j].displayName);
-            bytearray = (*env)->NewByteArray(env, nameLength);
-            if(bytearray == NULL) {
-                /* NewByteArray should have thrown an exception */
-                return NULL;
-            }
-            (*env)->SetByteArrayRegion(env, bytearray, (jint) 0, nameLength,
-                    (jbyte *)networkInterfaceArray.elements[j].displayName);
-            displayName = (*env)->CallStaticObjectMethod(env, utilClass, utilMid,
-                    bytearray, (jint) 0, nameLength);
-            if((*env)->ExceptionCheck(env)) {
-                return NULL;
-            }
-        }
-
-        /* generate the object with the inet addresses for the itnerface       */
-        for(i = 0; i < networkInterfaceArray.elements[j].numberAddresses; i++) {
-            element = structInToInetAddress(env, (struct in_addr *) &(networkInterfaceArray.elements[j].addresses[i].addr.inAddr));
-            if(i == 0) {
-                addresses = (*env)->NewObjectArray(env,
-                        networkInterfaceArray.elements[j].numberAddresses,
-                        inetAddressClass, element);
-            } else {
-                (*env)->SetObjectArrayElement(env, addresses, i, element);
-            }
-        }
-
-        /* now  create the NetworkInterface object for this interface and then add it it ot the arrary that will be returned */
-        currentInterface = (*env)->NewObject(env, networkInterfaceClass,
-                methodID, name, displayName, addresses,
-                networkInterfaceArray.elements[j].index);
-
-        if(j == 0) {
-            networkInterfaces = (*env)->NewObjectArray(env,
-                    networkInterfaceArray.length, networkInterfaceClass,
-                    currentInterface);
-        } else {
-            (*env)->SetObjectArrayElement(env, networkInterfaces, j, currentInterface);
-        }
-    }
-
-    /* free the memory for the interfaces struct and return the new NetworkInterface List */
-    sock_free_network_interface_struct(&networkInterfaceArray);
-    return networkInterfaces;
-}
-
-
-/*
- * JNI registration
- */
-static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
-    { "getNetworkInterfacesImpl", "()[Ljava/net/NetworkInterface;", getNetworkInterfacesImpl }
-};
-int register_java_net_NetworkInterface(JNIEnv* env) {
-    return jniRegisterNativeMethods(env, "java/net/NetworkInterface",
-        gMethods, NELEM(gMethods));
-
-}
diff --git a/libcore/luni/src/main/native/java_net_NetworkInterface.cpp b/libcore/luni/src/main/native/java_net_NetworkInterface.cpp
new file mode 100644
index 0000000..420c045
--- /dev/null
+++ b/libcore/luni/src/main/native/java_net_NetworkInterface.cpp
@@ -0,0 +1,152 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#include "AndroidSystemNatives.h"
+#include "JNIHelp.h"
+#include "jni.h"
+
+#include <errno.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include <net/if.h> // Note: Can't appear before <sys/socket.h> on OS X.
+
+#ifdef ANDROID
+#include "ifaddrs-android.h"
+#else
+#include <ifaddrs.h>
+#endif
+
+// Ensures we always call freeifaddrs(3) to clean up after getifaddrs(3).
+class ScopedInterfaceAddresses {
+public:
+    ScopedInterfaceAddresses() : list(NULL) {
+    }
+    
+    bool init() {
+        int rc = getifaddrs(&list);
+        return (rc != -1);
+    }
+    
+    ~ScopedInterfaceAddresses() {
+        freeifaddrs(list);
+    }
+    
+    ifaddrs* list;
+};
+
+// TODO: add a header file for shared utilities like this.
+extern jobject socketAddressToInetAddress(JNIEnv* env, sockaddr_storage* sockAddress);
+
+// TODO(enh): move to JNIHelp.h
+static void jniThrowSocketException(JNIEnv* env) {
+    char buf[BUFSIZ];
+    jniThrowException(env, "java/net/SocketException",
+            jniStrError(errno, buf, sizeof(buf)));
+}
+
+static jobject makeInterfaceAddress(JNIEnv* env, jint interfaceIndex, const char* name, sockaddr_storage* ss) {
+    jclass clazz = env->FindClass("java/net/InterfaceAddress");
+    if (clazz == NULL) {
+        return NULL;
+    }
+    jmethodID constructor = env->GetMethodID(clazz, "<init>", "(ILjava/lang/String;Ljava/net/InetAddress;)V");
+    if (constructor == NULL) {
+        return NULL;
+    }
+    jobject javaName = env->NewStringUTF(name);
+    if (javaName == NULL) {
+        return NULL;
+    }
+    jobject javaAddress = socketAddressToInetAddress(env, ss);
+    if (javaAddress == NULL) {
+        return NULL;
+    }
+    return env->NewObject(clazz, constructor, interfaceIndex, javaName, javaAddress);
+}
+
+static jobjectArray getInterfaceAddresses(JNIEnv* env, jclass) {
+    // Get the list of interface addresses.
+    ScopedInterfaceAddresses addresses;
+    if (!addresses.init()) {
+        jniThrowSocketException(env);
+        return NULL;
+    }
+    
+    // Count how many there are.
+    int interfaceAddressCount = 0;
+    for (ifaddrs* ifa = addresses.list; ifa != NULL; ifa = ifa->ifa_next) {
+        ++interfaceAddressCount;
+    }
+    
+    // Build the InterfaceAddress[]...
+    jclass interfaceAddressClass = env->FindClass("java/net/InterfaceAddress");
+    if (interfaceAddressClass == NULL) {
+        return NULL;
+    }
+    jobjectArray result = env->NewObjectArray(interfaceAddressCount, interfaceAddressClass, NULL);
+    if (result == NULL) {
+        return NULL;
+    }
+    
+    // And fill it in...
+    int arrayIndex = 0;
+    for (ifaddrs* ifa = addresses.list; ifa != NULL; ifa = ifa->ifa_next) {
+        // We're only interested in IP addresses.
+        int family = ifa->ifa_addr->sa_family;
+        if (family != AF_INET && family != AF_INET6) {
+            continue;
+        }
+        // Until we implement Java 6's NetworkInterface.isUp,
+        // we only want interfaces that are up.
+        if ((ifa->ifa_flags & IFF_UP) == 0) {
+            continue;
+        }
+        // Find the interface's index, and skip this address if
+        // the interface has gone away.
+        int interfaceIndex = if_nametoindex(ifa->ifa_name);
+        if (interfaceIndex == 0) {
+            continue;
+        }
+        // Make a new InterfaceAddress, and insert it into the array.
+        sockaddr_storage* ss = reinterpret_cast<sockaddr_storage*>(ifa->ifa_addr);
+        jobject element = makeInterfaceAddress(env, interfaceIndex, ifa->ifa_name, ss);
+        if (element == NULL) {
+            return NULL;
+        }
+        env->SetObjectArrayElement(result, arrayIndex, element);
+        if (env->ExceptionCheck()) {
+            return NULL;
+        }
+        ++arrayIndex;
+    }
+    return result;
+}
+
+static JNINativeMethod gMethods[] = {
+    /* name, signature, funcPtr */
+    { "getInterfaceAddresses", "()[Ljava/net/InterfaceAddress;", (void*) getInterfaceAddresses },
+};
+int register_java_net_NetworkInterface(JNIEnv* env) {
+    return jniRegisterNativeMethods(env, "java/net/NetworkInterface",
+            gMethods, NELEM(gMethods));
+}
diff --git a/libcore/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp b/libcore/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
index 635e1af..4d0eea6 100644
--- a/libcore/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
+++ b/libcore/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
@@ -308,25 +308,17 @@
     return !memcmp(mappedBytes, addressBytes, sizeof(mappedBytes));
 }
 
-/**
- * Converts a native address structure to an InetAddress object.
- * Throws a NullPointerException or an IOException in case of
- * error. This is signaled by a return value of -1. The normal
- * return value is 0.
- *
- * @param sockaddress the sockaddr_storage structure to convert
- *
- * @return a jobject representing an InetAddress
- */
-static jobject socketAddressToInetAddress(JNIEnv *env,
-        struct sockaddr_storage *sockaddress) {
+jobject byteArrayToInetAddress(JNIEnv* env, jbyteArray byteArray) {
+    return env->CallStaticObjectMethod(gCachedFields.iaddr_class,
+            gCachedFields.iaddr_getbyaddress, byteArray);
+}
+
+jobject socketAddressToInetAddress(JNIEnv *env, sockaddr_storage* sockaddress) {
 
     jbyteArray byteArray = socketAddressToByteArray(env, sockaddress);
     if (byteArray == NULL)  // Exception has already been thrown.
         return NULL;
-
-    return env->CallStaticObjectMethod(gCachedFields.iaddr_class,
-            gCachedFields.iaddr_getbyaddress, byteArray);
+    return byteArrayToInetAddress(env, byteArray);
 }
 
 /**
@@ -3102,8 +3094,11 @@
                 throwSocketException(env, convertError(errno));
                 return NULL;
             }
-            // This option is IPv4-only.
-            sockVal.ss_family = AF_INET;
+            if (sockVal.ss_family != AF_INET) {
+                // Java expects an AF_INET INADDR_ANY, but Linux just returns AF_UNSPEC.
+                jbyteArray inAddrAny = env->NewByteArray(4); // { 0, 0, 0, 0 }
+                return byteArrayToInetAddress(env, inAddrAny);
+            }
             return socketAddressToInetAddress(env, &sockVal);
         }
         case JAVASOCKOPT_IP_MULTICAST_IF2: {
diff --git a/libcore/luni/src/main/native/sub.mk b/libcore/luni/src/main/native/sub.mk
index d277f82..184a13d 100644
--- a/libcore/luni/src/main/native/sub.mk
+++ b/libcore/luni/src/main/native/sub.mk
@@ -13,7 +13,7 @@
 	java_lang_Math.c \
 	java_lang_StrictMath.c \
 	java_net_InetAddress.cpp \
-	java_net_NetworkInterface.c \
+	java_net_NetworkInterface.cpp \
 	cbigint.c \
 	commonDblParce.c \
 	org_apache_harmony_luni_util_fltparse.c \
diff --git a/libcore/luni/src/test/java/tests/api/java/net/MulticastSocketTest.java b/libcore/luni/src/test/java/tests/api/java/net/MulticastSocketTest.java
index 1429063..018d58a 100644
--- a/libcore/luni/src/test/java/tests/api/java/net/MulticastSocketTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/net/MulticastSocketTest.java
@@ -17,11 +17,6 @@
 
 package tests.api.java.net;
 
-import dalvik.annotation.KnownFailure; 
-import dalvik.annotation.TestTargetClass; 
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.io.IOException;
 import java.net.BindException;
 import java.net.DatagramPacket;
@@ -34,290 +29,205 @@
 import java.net.SocketAddress;
 import java.net.SocketException;
 import java.net.UnknownHostException;
-import java.security.Permission;
+import java.util.ArrayList;
 import java.util.Enumeration;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.TimeUnit;
 
 import tests.support.Support_NetworkInterface;
 import tests.support.Support_PortManager;
 
-@TestTargetClass(MulticastSocket.class) 
 public class MulticastSocketTest extends SocketTestCase {
 
-    Thread t;
+	Thread t;
 
-    MulticastSocket mss;
+	MulticastSocket mss;
 
-    MulticastServer server;
+	MulticastServer server;
 
-    // private member variables used for tests
-    boolean atLeastOneInterface = false;
+	// private member variables used for tests
+	boolean atLeastOneInterface = false;
 
-    boolean atLeastTwoInterfaces = false;
+	boolean atLeastTwoInterfaces = false;
 
-    private NetworkInterface networkInterface1 = null;
+	private NetworkInterface networkInterface1 = null;
 
-    private NetworkInterface networkInterface2 = null;
+	private NetworkInterface networkInterface2 = null;
 
-    private NetworkInterface IPV6networkInterface1 = null;
+	private NetworkInterface IPV6networkInterface1 = null;
 
-    static class MulticastServer extends Thread {
+	static class MulticastServer extends Thread {
 
-        public MulticastSocket ms;
+		public MulticastSocket ms;
 
-        volatile boolean running = true;
+		boolean running = true;
 
-        private final BlockingQueue<DatagramPacket> queue
-                = new ArrayBlockingQueue<DatagramPacket>(1);
+		volatile public byte[] rbuf = new byte[512];
+
+        volatile DatagramPacket rdp = null;
+        
+        private InetAddress groupAddr = null;
+        private SocketAddress groupSockAddr = null;
+        private NetworkInterface groupNI = null;
 
         public void run() {
-            try {
+			try {
+                byte[] tmpbuf = new byte[512];
+                DatagramPacket tmpPack =
+                        new DatagramPacket(tmpbuf, tmpbuf.length);
+                
                 while (running) {
-                    try {
-                        byte[] rbuf = new byte[512];
-                        rbuf[0] = -1;
-                        DatagramPacket rdp = new DatagramPacket(rbuf, rbuf.length);
-                        ms.receive(rdp);
-                        queue.put(rdp);
+					try {
+                        ms.receive(tmpPack);
+                        
+                        System.arraycopy(tmpPack.getData(), 0, rdp.getData(),
+                                rdp.getOffset(), tmpPack.getLength());
+                        rdp.setLength(tmpPack.getLength());
+                        rdp.setAddress(tmpPack.getAddress());
+                        rdp.setPort(tmpPack.getPort());
                     } catch (java.io.InterruptedIOException e) {
-                    } catch (InterruptedException e) {
-                    }
-                }
-            } catch (java.io.IOException e) {
-                System.out.println("Multicast server failed: " + e);
-            } finally {
-                ms.close();
-            }
-        }
+                        Thread.yield();
+					}
+				}
+			} catch (java.io.IOException e) {
+				System.out.println("Multicast server failed: " + e);
+			} finally {
+				ms.close();
+			}
+		}
 
-        public synchronized void leaveGroup(InetAddress aGroup)
-                throws java.io.IOException {
-            ms.leaveGroup(aGroup);
+		public void stopServer() {
+			running = false;
+            try {
+                if (groupAddr != null) {
+                    ms.leaveGroup(groupAddr);
+                } else if (groupSockAddr != null) {
+                    ms.leaveGroup(groupSockAddr, groupNI);
+                }
+            } catch (IOException e) {}
         }
 
         public MulticastServer(InetAddress anAddress, int aPort)
                 throws java.io.IOException {
+            rbuf = new byte[512];
+            rbuf[0] = -1;
+            rdp = new DatagramPacket(rbuf, rbuf.length);
             ms = new MulticastSocket(aPort);
             ms.setSoTimeout(2000);
-            ms.joinGroup(anAddress);
+            groupAddr = anAddress;
+            ms.joinGroup(groupAddr);
         }
-
+        
+        
         public MulticastServer(SocketAddress anAddress, int aPort,
-                NetworkInterface netInterface) throws java.io.IOException {
-            ms = new MulticastSocket(aPort);
-            ms.setSoTimeout(2000);
-            ms.joinGroup(anAddress, netInterface);
-        }
+				NetworkInterface netInterface) throws java.io.IOException {
+			rbuf = new byte[512];
+			rbuf[0] = -1;
+			rdp = new DatagramPacket(rbuf, rbuf.length);
+			ms = new MulticastSocket(aPort);
+			ms.setSoTimeout(2000);
+            groupSockAddr = anAddress;
+            groupNI = netInterface;
+            ms.joinGroup(groupSockAddr, groupNI);
+		}
+	}
 
-        public DatagramPacket receive() throws InterruptedException {
-            return queue.poll(1000, TimeUnit.MILLISECONDS);
-        }
-
-        public void stopServer() throws InterruptedException {
-            running = false;
-            interrupt();
-            join();
-        }
-    }
-
-    /**
-     * @tests java.net.MulticastSocket#MulticastSocket()
-     */
-    @TestTargetNew(
-        level = TestLevel.SUFFICIENT,
-        notes = "IOException exception checking missed.",
-        method = "MulticastSocket",
-        args = {}
-    )
-    public void test_Constructor() throws IOException {
-        // regression test for 497
+	/**
+	 * @tests java.net.MulticastSocket#MulticastSocket()
+	 */
+	public void test_Constructor() throws IOException {
+		// regression test for 497
         MulticastSocket s = new MulticastSocket();
         // regression test for Harmony-1162
         assertTrue(s.getReuseAddress());
-        
-        SecurityManager sm = new SecurityManager() {
+	}
 
-            public void checkPermission(Permission perm) {
-            }
-            
-            public void checkListen(int port) {
-                throw new SecurityException();
-            }
-        };
-
-        SecurityManager oldSm = System.getSecurityManager();
-        System.setSecurityManager(sm);
-        try {
-            new MulticastSocket();
-            fail("SecurityException should be thrown.");
-        } catch (SecurityException e) {
-            // expected
-        } catch (SocketException e) {
-            fail("SocketException was thrown.");
-        } catch (IOException e) {
-            fail("IOException was thrown.");
-            e.printStackTrace();
-        } finally {
-            System.setSecurityManager(oldSm);
-        } 
-    }
-
-    /**
-     * @tests java.net.MulticastSocket#MulticastSocket(int)
-     */
-    @TestTargetNew(
-        level = TestLevel.SUFFICIENT,
-        notes = "IOException exception checking missed.",
-        method = "MulticastSocket",
-        args = {int.class}
-    )
-    public void test_ConstructorI() {
-        // Test for method java.net.MulticastSocket(int)
-        // Used in tests
-        MulticastSocket dup = null;
-        try {
-            mss = new MulticastSocket();
-            int port = mss.getLocalPort();
-            dup = new MulticastSocket(port);
+	/**
+	 * @tests java.net.MulticastSocket#MulticastSocket(int)
+	 */
+	public void test_ConstructorI() throws IOException {
+	    MulticastSocket orig = new MulticastSocket();
+        int port = orig.getLocalPort();
+        orig.close();
+		MulticastSocket dup = null;
+		try {
+			dup = new MulticastSocket(port);
             // regression test for Harmony-1162
             assertTrue(dup.getReuseAddress());
-        } catch (IOException e) {
-            fail("duplicate binding not allowed: " + e);
-        }
-        
-        
-        
-        if (dup != null)
-            dup.close();
-        
-        SecurityManager sm = new SecurityManager() {
+		} catch (IOException e) {
+			fail("duplicate binding not allowed: " + e);
+		}
+		if (dup != null)
+			dup.close();
+	}
 
-            public void checkPermission(Permission perm) {
-            }
-            
-            public void checkListen(int port) {
-                throw new SecurityException();
-            }
-        };
+	/**
+	 * @tests java.net.MulticastSocket#getInterface()
+	 */
+	public void test_getInterface() throws Exception {
+		// Test for method java.net.InetAddress
+		// java.net.MulticastSocket.getInterface()
+		assertTrue("Used for testing.", true);
 
-        SecurityManager oldSm = System.getSecurityManager();
-        System.setSecurityManager(sm);
-        try {
-            new MulticastSocket(1);
-            fail("SecurityException should be thrown.");
-        } catch (SecurityException e) {
-            // expected
-        } catch (SocketException e) {
-            fail("SocketException was thrown.");
-        } catch (IOException e) {
-            fail("IOException was thrown.");
-            e.printStackTrace();
-        } finally {
-            System.setSecurityManager(oldSm);
-        } 
-    }
+		int groupPort = Support_PortManager.getNextPortForUDP();
 
-    /**
-     * @tests java.net.MulticastSocket#getInterface()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getInterface",
-        args = {}
-    )
-    @KnownFailure("No interfaces if there's no debugger connected")
-    public void test_getInterface() {
-        // Test for method java.net.InetAddress
-        // java.net.MulticastSocket.getInterface()
-        assertTrue("Used for testing.", true);
+                if (atLeastOneInterface) {
+                        // validate that we get the expected response when one was not
+                        // set
+                        mss = new MulticastSocket(groupPort);
+                        String preferIPv4StackValue = System
+                                        .getProperty("java.net.preferIPv4Stack");
+                        String preferIPv6AddressesValue = System
+                                        .getProperty("java.net.preferIPv6Addresses");
+                        if (((preferIPv4StackValue == null) || preferIPv4StackValue
+                                        .equalsIgnoreCase("false"))
+                                        && (preferIPv6AddressesValue != null)
+                                        && (preferIPv6AddressesValue.equals("true"))) {
+                                // we expect an IPv6 ANY in this case
+                                assertEquals("inet Address returned when not set",
+                                             InetAddress.getByName("::0"),
+                                             mss.getInterface());
+                        } else {
+                                // we expect an IPv4 ANY in this case
+                                assertEquals("inet Address returned when not set",
+                                             InetAddress.getByName("0.0.0.0"),
+                                             mss.getInterface());
+                        }
 
-        int groupPort = Support_PortManager.getNextPortForUDP();
-        try {
-            if (atLeastOneInterface) {
-                // validate that we get the expected response when one was not
-                // set
-                mss = new MulticastSocket(groupPort);
-                String preferIPv4StackValue = System
-                        .getProperty("java.net.preferIPv4Stack");
-                String preferIPv6AddressesValue = System
-                        .getProperty("java.net.preferIPv6Addresses");
-                if (((preferIPv4StackValue == null) || preferIPv4StackValue
-                        .equalsIgnoreCase("false"))
-                        && (preferIPv6AddressesValue != null)
-                        && (preferIPv6AddressesValue.equals("true"))) {
-                    // we expect an IPv6 ANY in this case
-                    assertTrue("inet Address returned when not set:"
-                            + mss.getInterface().toString(), InetAddress
-                            .getByName("::0").equals(mss.getInterface()));
-                } else {
-                    // we expect an IPv4 ANY in this case
-                    assertNotNull("inet Address returned when not set:", 
-                            mss.getInterface());
+                        // validate that we get the expected response when we set via
+                        // setInterface
+                        Enumeration addresses = networkInterface1.getInetAddresses();
+                        if (addresses.hasMoreElements()) {
+                                InetAddress firstAddress = (InetAddress) addresses
+                                                .nextElement();
+                                mss.setInterface(firstAddress);
+                                assertEquals("getNetworkInterface did not return interface set by setInterface",
+                                             firstAddress, mss.getInterface());
+
+                                groupPort = Support_PortManager.getNextPortForUDP();
+                                mss = new MulticastSocket(groupPort);
+                                mss.setNetworkInterface(networkInterface1);
+                                assertEquals("getInterface did not return interface set by setNetworkInterface",
+                                             networkInterface1,
+                                             NetworkInterface.getByInetAddress(mss.getInterface()));
+                        }
+
                 }
+	}
 
-                // validate that we get the expected response when we set via
-                // setInterface
-                Enumeration addresses = networkInterface1.getInetAddresses();
-                if (addresses != null) {
-                    InetAddress firstAddress = (InetAddress) addresses
-                            .nextElement();
-                    mss.setInterface(firstAddress);
-                    assertTrue(
-                            "getNetworkInterface did not return interface set " +
-                            "by setInterface.  Expected:"
-                                    + firstAddress + " Got:"
-                                    + mss.getInterface(), firstAddress
-                                    .equals(mss.getInterface()));
-
-                    groupPort = Support_PortManager.getNextPortForUDP();
-                    mss = new MulticastSocket(groupPort);
-                    mss.setNetworkInterface(networkInterface1);
-                    InetAddress addr = mss.getInterface();
-                    NetworkInterface if1 = NetworkInterface.getByInetAddress(addr);
-                    assertEquals(
-                            "getInterface did not return interface set by " +
-                            "setNeworkInterface Expected: " + firstAddress
-                                    + "Got:" + mss.getInterface(),
-                                    networkInterface1, if1);
-                }
-                mss.close();
-                try {
-                    mss.getInterface();
-                    fail("SocketException was not thrown.");
-                } catch(SocketException ioe) {
-                    //expected
-                }
-            }
-        } catch (Exception e) {
-            fail("Exception during getInterface test: " + e.toString());
-        }
-    }
-
-    /**
-     * @throws IOException 
-     * @tests java.net.MulticastSocket#getNetworkInterface()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getNetworkInterface",
-        args = {}
-    )
-    @KnownFailure("No interfaces if there's no debugger connected")
-    public void test_getNetworkInterface() throws IOException {
+	/**
+	 * @throws IOException
+	 * @tests java.net.MulticastSocket#getNetworkInterface()
+	 */
+	public void test_getNetworkInterface() throws IOException {
         int groupPort = Support_PortManager.getNextPortForUDP();
         if (atLeastOneInterface) {
             // validate that we get the expected response when one was not
             // set
             mss = new MulticastSocket(groupPort);
             NetworkInterface theInterface = mss.getNetworkInterface();
-            assertNotNull(
-                    "network interface returned wrong network interface when " +
-                    "not set:"
-                            + theInterface, theInterface.getInetAddresses());
+            assertTrue(
+                    "network interface returned wrong network interface when not set:"
+                            + theInterface, theInterface.getInetAddresses()
+                            .hasMoreElements());
             InetAddress firstAddress = (InetAddress) theInterface
                     .getInetAddresses().nextElement();
             // validate we the first address in the network interface is the
@@ -330,42 +240,34 @@
                     .equalsIgnoreCase("false"))
                     && (preferIPv6AddressesValue != null)
                     && (preferIPv6AddressesValue.equals("true"))) {
-                assertTrue(
-                        "network interface returned wrong network interface " +
-                        "when not set:"
-                                + theInterface, InetAddress.getByName("::0")
-                                .equals(firstAddress));
+                assertEquals("network interface returned wrong network interface when not set:"
+                             + theInterface,
+                             firstAddress, InetAddress.getByName("::0"));
 
             } else {
-                assertTrue(
-                        "network interface returned wrong network interface " +
-                        "when not set:"
-                                + theInterface, InetAddress
-                                .getByName("0.0.0.0").equals(firstAddress));
+                assertEquals("network interface returned wrong network interface when not set:"
+                             + theInterface,
+                             InetAddress.getByName("0.0.0.0"),
+                             firstAddress);
             }
 
             mss.setNetworkInterface(networkInterface1);
-            assertTrue(
-                    "getNetworkInterface did not return interface set by " +
-                    "setNeworkInterface",
-                    networkInterface1.equals(mss.getNetworkInterface()));
+            assertEquals("getNetworkInterface did not return interface set by setNeworkInterface",
+                         networkInterface1, mss.getNetworkInterface());
 
             if (atLeastTwoInterfaces) {
                 mss.setNetworkInterface(networkInterface2);
-                assertTrue(
-                        "getNetworkInterface did not return network interface " +
-                        "set by second setNetworkInterface call",
-                        networkInterface2.equals(mss.getNetworkInterface()));
+                assertEquals("getNetworkInterface did not return network interface set by second setNetworkInterface call",
+                             networkInterface2, mss.getNetworkInterface());
             }
 
             groupPort = Support_PortManager.getNextPortForUDP();
             mss = new MulticastSocket(groupPort);
             if (IPV6networkInterface1 != null) {
                 mss.setNetworkInterface(IPV6networkInterface1);
-                assertTrue(
-                        "getNetworkInterface did not return interface set " +
-                        "by setNeworkInterface",
-                        IPV6networkInterface1.equals(mss.getNetworkInterface()));
+                assertEquals("getNetworkInterface did not return interface set by setNeworkInterface",
+                             IPV6networkInterface1,
+                             mss.getNetworkInterface());
             }
 
             // validate that we get the expected response when we set via
@@ -373,191 +275,100 @@
             groupPort = Support_PortManager.getNextPortForUDP();
             mss = new MulticastSocket(groupPort);
             Enumeration addresses = networkInterface1.getInetAddresses();
-            if (addresses != null) {
+            if (addresses.hasMoreElements()) {
                 firstAddress = (InetAddress) addresses.nextElement();
                 mss.setInterface(firstAddress);
-                assertTrue(
-                        "getNetworkInterface did not return interface set " +
-                        "by setInterface",
-                        networkInterface1.equals(mss.getNetworkInterface()));
-            }
-            
-            mss.close();
-            try {
-                mss.getNetworkInterface();
-                fail("SocketException was not thrown.");
-            } catch(SocketException ioe) {
-                //expected
+                assertEquals("getNetworkInterface did not return interface set by setInterface",
+                             networkInterface1,
+                             mss.getNetworkInterface());
             }
         }
     }
 
-    /**
-     * @tests java.net.MulticastSocket#getTimeToLive()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getTimeToLive",
-        args = {}
-    )
-    public void test_getTimeToLive() {
-        try {
-            mss = new MulticastSocket();
-            mss.setTimeToLive(120);
-            assertTrue("Returned incorrect 1st TTL: " + mss.getTimeToLive(),
-                    mss.getTimeToLive() == 120);
-            mss.setTimeToLive(220);
-            assertTrue("Returned incorrect 2nd TTL: " + mss.getTimeToLive(),
-                    mss.getTimeToLive() == 220);
-            mss.close();
-            try {
-                mss.getTimeToLive();
-                fail("IOException was not thrown.");
-            } catch(IOException ioe) {
-                //expected
-            }
-            ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
-        } catch (Exception e) {
-            handleException(e, SO_MULTICAST);
-        }
-    }
+	/**
+	 * @tests java.net.MulticastSocket#getTimeToLive()
+	 */
+	public void test_getTimeToLive() {
+		try {
+			mss = new MulticastSocket();
+			mss.setTimeToLive(120);
+			assertEquals("Returned incorrect 1st TTL",
+                                     120, mss.getTimeToLive());
+			mss.setTimeToLive(220);
+			assertEquals("Returned incorrect 2nd TTL",
+                                     220, mss.getTimeToLive());
+			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
+		} catch (Exception e) {
+			handleException(e, SO_MULTICAST);
+		}
+	}
 
-    /**
-     * @tests java.net.MulticastSocket#getTTL()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getTTL",
-        args = {}
-    )
-    public void test_getTTL() {
-        // Test for method byte java.net.MulticastSocket.getTTL()
+	/**
+	 * @tests java.net.MulticastSocket#getTTL()
+	 */
+	public void test_getTTL() {
+		// Test for method byte java.net.MulticastSocket.getTTL()
 
-        try {
-            mss = new MulticastSocket();
-            mss.setTTL((byte) 120);
-            assertTrue("Returned incorrect TTL: " + mss.getTTL(),
-                    mss.getTTL() == 120);
-            mss.close();
-            try {
-                mss.getTTL();
-                fail("IOException was not thrown.");
-            } catch(IOException ioe) {
-                //expected
-            }
-            ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
-        } catch (Exception e) {
-            handleException(e, SO_MULTICAST);
-        }
-    }
+		try {
+			mss = new MulticastSocket();
+			mss.setTTL((byte) 120);
+			assertEquals("Returned incorrect TTL",
+                                     120, mss.getTTL());
+			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
+		} catch (Exception e) {
+			handleException(e, SO_MULTICAST);
+		}
+	}
 
-    /**
-     * @tests java.net.MulticastSocket#joinGroup(java.net.InetAddress)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "joinGroup",
-        args = {java.net.InetAddress.class}
-    )
-    public void test_joinGroupLjava_net_InetAddress() throws InterruptedException {
-        // Test for method void
-        // java.net.MulticastSocket.joinGroup(java.net.InetAddress)
-        String msg = null;
-        InetAddress group = null;
-        int[] ports = Support_PortManager.getNextPortsForUDP(2);
-        int groupPort = ports[0];
-        try {
-            group = InetAddress.getByName("224.0.0.3");
-            server = new MulticastServer(group, groupPort);
-            server.start();
-            Thread.sleep(1000);
-            msg = "Hello World";
-            mss = new MulticastSocket(ports[1]);
-            DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg
-                    .length(), group, groupPort);
-            mss.joinGroup(group);
-            mss.send(sdp, (byte) 10);
+	/**
+	 * @tests java.net.MulticastSocket#joinGroup(java.net.InetAddress)
+	 */
+	public void test_joinGroupLjava_net_InetAddress() throws Exception {
+		// Test for method void
+		// java.net.MulticastSocket.joinGroup(java.net.InetAddress)
+                String msg = null;
+		InetAddress group = null;
+		int[] ports = Support_PortManager.getNextPortsForUDP(2);
+		int groupPort = ports[0];
+                group = InetAddress.getByName("224.0.0.3");
+                server = new MulticastServer(group, groupPort);
+                server.start();
+                Thread.sleep(1000);
+                msg = "Hello World";
+                mss = new MulticastSocket(ports[1]);
+                DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg
+                                .length(), group, groupPort);
+                mss.send(sdp, (byte) 10);
+                Thread.sleep(1000);
 
-            SecurityManager sm = new SecurityManager() {
+                assertEquals("Group member did not recv data",
+                             msg,
+                             new String(server.rdp.getData(), 0, server.rdp.getLength()));
+	}
 
-                public void checkPermission(Permission perm) {
-                }
-                
-                public void checkMulticast(InetAddress maddr) {
-                    throw new SecurityException();
-                }
-            };
+	/**
+	 * @throws IOException 
+	 * @throws InterruptedException 
+	 * @tests java.net.MulticastSocket#joinGroup(java.net.SocketAddress,java.net.NetworkInterface)
+	 */
+	public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface() throws IOException, InterruptedException {
+		// security manager that allows us to check that we only return the
+		// addresses that we should
+		class mySecurityManager extends SecurityManager {
 
-            SecurityManager oldSm = System.getSecurityManager();
-            System.setSecurityManager(sm);
-            try {
-                mss.joinGroup(group);
-                fail("SecurityException should be thrown.");
-            } catch (SecurityException e) {
-                // expected
-            } catch (SocketException e) {
-                fail("SocketException was thrown.");
-            } catch (IOException e) {
-                fail("IOException was thrown.");
-                e.printStackTrace();
-            } finally {
-                System.setSecurityManager(oldSm);
-            } 
-            
-            mss.close();
-            try {
-                mss.joinGroup(group);
-                fail("SocketException was not thrown.");
-            } catch(SocketException ioe) {
-                //expected
-            }
-        } catch (Exception e) {
-            fail("Exception during joinGroup test: " + e.toString());
-        }
-        DatagramPacket rdb = server.receive();
+			public void checkMulticast(InetAddress address) {
+				throw new SecurityException("not allowed");
+			}
+		}
 
-        assertEquals("Group member did not recv data: ", msg,
-                new String(rdb.getData(), 0, rdb.getLength()));
+		String msg = null;
+		InetAddress group = null;
+		SocketAddress groupSockAddr = null;
+		int[] ports = Support_PortManager.getNextPortsForUDP(2);
+		int groupPort = ports[0];
+		int serverPort = ports[1];
 
-    }
-
-    /**
-     * @throws IOException 
-     * @throws InterruptedException 
-     * @tests java.net.MulticastSocket#joinGroup(java.net.SocketAddress,
-     *                                              java.net.NetworkInterface)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "joinGroup",
-        args = {java.net.SocketAddress.class, java.net.NetworkInterface.class}
-    )
-    public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface() 
-                                    throws IOException, InterruptedException {
-        // security manager that allows us to check that we only return the
-        // addresses that we should
-        class mySecurityManager extends SecurityManager {
-
-            public void checkPermission(Permission perm) {
-            }
-            
-            public void checkMulticast(InetAddress address) {
-                throw new SecurityException("not allowed");
-            }
-        }
-
-        String msg = null;
-        InetAddress group = null;
-        SocketAddress groupSockAddr = null;
-        int[] ports = Support_PortManager.getNextPortsForUDP(2);
-        int groupPort = ports[0];
-        int serverPort = ports[1];
-
-            Enumeration theInterfaces = NetworkInterface.getNetworkInterfaces();
+        Enumeration<NetworkInterface> theInterfaces = NetworkInterface.getNetworkInterfaces();
 
         // first validate that we handle a null group ok
         mss = new MulticastSocket(groupPort);
@@ -613,11 +424,11 @@
                     .length(), group, serverPort);
             mss.setTimeToLive(2);
             mss.send(sdp);
-            DatagramPacket rdp = server.receive();
-
+            Thread.sleep(1000);
             // now vaildate that we received the data as expected
-            assertEquals("Group member did not recv data: ", msg,
-                    new String(rdp.getData(), 0, rdp.getLength()));
+            assertEquals("Group member did not recv data",
+                         msg,
+                         new String(server.rdp.getData(), 0, server.rdp.getLength()));
             server.stopServer();
 
             // now validate that we handled the case were we join a
@@ -638,9 +449,11 @@
             sdp = new DatagramPacket(msg.getBytes(), msg.length(), group2,
                     serverPort);
             mss.send(sdp);
-            rdp = server.receive();
-            assertNull("Group member received data when sent on different group",
-                    rdp);
+            Thread.sleep(1000);
+            assertFalse(
+                    "Group member received data when sent on different group: ",
+                    new String(server.rdp.getData(), 0, server.rdp.getLength())
+                            .equals(msg));
             server.stopServer();
 
             // if there is more than one network interface then check that
@@ -651,39 +464,47 @@
                 NetworkInterface loopbackInterface = NetworkInterface
                         .getByInetAddress(InetAddress.getByName("127.0.0.1"));
 
+                boolean anyLoop = networkInterface1.equals(loopbackInterface) || networkInterface2.equals(loopbackInterface);
+                
+                ArrayList<NetworkInterface> realInterfaces = new ArrayList<NetworkInterface>();
                 theInterfaces = NetworkInterface.getNetworkInterfaces();
                 while (theInterfaces.hasMoreElements()) {
-
-                    NetworkInterface thisInterface = (NetworkInterface) 
-                                                    theInterfaces.nextElement();
-                    if ((thisInterface.getInetAddresses() != null && thisInterface
-                            .getInetAddresses().hasMoreElements())
+                    NetworkInterface thisInterface = (NetworkInterface) theInterfaces.nextElement();
+                    if (thisInterface.getInetAddresses().hasMoreElements()
                             && (Support_NetworkInterface
-                                    .useInterface(thisInterface) == true)) {
+                                    .useInterface(thisInterface) == true)){
+                        realInterfaces.add(thisInterface);
+                    }
+                }
+                
+                for (int i = 0; i < realInterfaces.size(); i++) {
+                    final int SECOND = 1;
+                    NetworkInterface thisInterface = realInterfaces.get(i);
+                   
                         // get the first address on the interface
 
                         // start server which is joined to the group and has
                         // only asked for packets on this interface
-                        Enumeration addresses = thisInterface
-                                .getInetAddresses();
+                        Enumeration<InetAddress> addresses = thisInterface.getInetAddresses();
 
                         NetworkInterface sendingInterface = null;
-                        boolean isLoopback = false;
-                        if (addresses != null) {
-                            InetAddress firstAddress = (InetAddress) addresses
-                                    .nextElement();
-                            if (firstAddress.isLoopbackAddress()) {
-                                isLoopback = true;
-                            }
+                        if (addresses.hasMoreElements()) {
+                            InetAddress firstAddress = (InetAddress) addresses.nextElement();
                             if (firstAddress instanceof Inet4Address) {
                                 group = InetAddress.getByName("224.0.0.4");
-                                if (networkInterface1.equals(NetworkInterface
-                                        .getByInetAddress(InetAddress
-                                                .getByName("127.0.0.1")))) {
-                                    sendingInterface = networkInterface2;
+                                if (anyLoop) {
+                                    if (networkInterface1.equals(loopbackInterface)) {
+                                        sendingInterface = networkInterface2;
+                                    } else {
+                                        sendingInterface = networkInterface1;
+                                    }
                                 } else {
-                                    sendingInterface = networkInterface1;
+                                    if(i == SECOND){
+                                        sendingInterface = networkInterface2;
+                                    } else {
+                                        sendingInterface = networkInterface1;
                                 }
+                               }
                             } else {
                                 // if this interface only seems to support
                                 // IPV6 addresses
@@ -693,13 +514,6 @@
                             }
                         }
 
-                        InetAddress useAddress = null;
-                        addresses = sendingInterface.getInetAddresses();
-                        if ((addresses != null)
-                                && (addresses.hasMoreElements())) {
-                            useAddress = (InetAddress) addresses.nextElement();
-                        }
-
                         ports = Support_PortManager.getNextPortsForUDP(2);
                         serverPort = ports[0];
                         groupPort = ports[1];
@@ -712,33 +526,27 @@
                         // Now send out a package on interface
                         // networkInterface 1. We should
                         // only see the packet if we send it on interface 1
-                        InetSocketAddress theAddress = new InetSocketAddress(
-                                useAddress, groupPort);
                         mss = new MulticastSocket(groupPort);
                         mss.setNetworkInterface(sendingInterface);
                         msg = "Hello World - Again" + thisInterface.getName();
                         sdp = new DatagramPacket(msg.getBytes(), msg.length(),
                                 group, serverPort);
                         mss.send(sdp);
-                        rdp = server.receive();
-
+                        Thread.sleep(1000);
                         if (thisInterface.equals(sendingInterface)) {
-                            assertEquals(
-                                    "Group member did not recv data when " +
-                                    "bound on specific interface: ", msg,
-                                    new String(rdp.getData(), 0, rdp.getLength()));
+                            assertEquals("Group member did not recv data when bound on specific interface",
+                                         msg,
+                                         new String(server.rdp.getData(), 0, server.rdp.getLength()));
                         } else {
                             assertFalse(
-                                    "Group member received data on other " +
-                                    "interface when only asked for it on one " +
-                                    "interface: ",
-                                    new String(rdp.getData(), 0,
-                                            rdp.getLength()).equals(msg));
+                                    "Group member received data on other interface when only asked for it on one interface: ",
+                                    new String(server.rdp.getData(), 0,
+                                            server.rdp.getLength()).equals(msg));
                         }
 
                         server.stopServer();
                     }
-                }
+                
 
                 // validate that we can join the same address on two
                 // different interfaces but not on the same interface
@@ -748,373 +556,252 @@
                 mss.joinGroup(groupSockAddr, networkInterface2);
                 try {
                     mss.joinGroup(groupSockAddr, networkInterface1);
-                    fail("Did not get expected exception when joining for " +
-                            "second time on same interface");
+                    fail("Did not get expected exception when joining for second time on same interface");
                 } catch (IOException e) {
                 }
             }
         }
-        System.setSecurityManager(null);
-    }
+		System.setSecurityManager(null);
+	}
 
-    /**
-     * @tests java.net.MulticastSocket#leaveGroup(java.net.InetAddress)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "leaveGroup",
-        args = {java.net.InetAddress.class}
-    )
-    public void test_leaveGroupLjava_net_InetAddress() {
-        // Test for method void
-        // java.net.MulticastSocket.leaveGroup(java.net.InetAddress)
-        String msg = null;
-        boolean except = false;
-        InetAddress group = null;
-        int[] ports = Support_PortManager.getNextPortsForUDP(2);
-        int groupPort = ports[0];
+	/**
+	 * @tests java.net.MulticastSocket#leaveGroup(java.net.InetAddress)
+	 */
+	public void test_leaveGroupLjava_net_InetAddress() {
+		// Test for method void
+		// java.net.MulticastSocket.leaveGroup(java.net.InetAddress)
+		String msg = null;
+		boolean except = false;
+		InetAddress group = null;
+		int[] ports = Support_PortManager.getNextPortsForUDP(2);
+		int groupPort = ports[0];
 
-        try {
-            group = InetAddress.getByName("224.0.0.3");
-            msg = "Hello World";
-            mss = new MulticastSocket(ports[1]);
-            DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg
-                    .length(), group, groupPort);
-            mss.send(sdp, (byte) 10);
-            ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
-        } catch (Exception e) {
-            handleException(e, SO_MULTICAST);
-        }
-        try {
-            // Try to leave s group that mss is not a member of
-            mss.leaveGroup(group);
-        } catch (java.io.IOException e) {
-            // Correct
-            except = true;
-        }
-        assertTrue("Failed to throw exception leaving non-member group", except);
-        
-        SecurityManager sm = new SecurityManager() {
+		try {
+			group = InetAddress.getByName("224.0.0.3");
+			msg = "Hello World";
+			mss = new MulticastSocket(ports[1]);
+			DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg
+					.length(), group, groupPort);
+			mss.send(sdp, (byte) 10);
+			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
+		} catch (Exception e) {
+			handleException(e, SO_MULTICAST);
+		}
+		try {
+			// Try to leave s group that mss is not a member of
+			mss.leaveGroup(group);
+		} catch (java.io.IOException e) {
+			// Correct
+			except = true;
+		}
+		assertTrue("Failed to throw exception leaving non-member group", except);
+	}
 
-            public void checkPermission(Permission perm) {
-            }
-            
-            public void checkMulticast(InetAddress maddr) {
-                throw new SecurityException();
-            }
-        };
+	/**
+	 * @tests java.net.MulticastSocket#leaveGroup(java.net.SocketAddress,java.net.NetworkInterface)
+	 */
+	public void test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface() throws Exception {
+		// security manager that allows us to check that we only return the
+		// addresses that we should
+		class mySecurityManager extends SecurityManager {
 
-        SecurityManager oldSm = System.getSecurityManager();
-        System.setSecurityManager(sm);
-        try {
-            mss.leaveGroup(group);
-            fail("SecurityException should be thrown.");
-        } catch (SecurityException e) {
-            // expected
-        } catch (SocketException e) {
-            fail("SocketException was thrown.");
-        } catch (IOException e) {
-            fail("IOException was thrown.");
-            e.printStackTrace();
-        } finally {
-            System.setSecurityManager(oldSm);
-        } 
-    }
+			public void checkMulticast(InetAddress address) {
+				throw new SecurityException("not allowed");
+			}
+		}
 
-    /**
-     * @tests java.net.MulticastSocket#leaveGroup(java.net.SocketAddress,
-     * java.net.NetworkInterface)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "leaveGroup",
-        args = {java.net.SocketAddress.class, java.net.NetworkInterface.class}
-    )
-    public void test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface() {
-        // security manager that allows us to check that we only return the
-        // addresses that we should
-        class mySecurityManager extends SecurityManager {
-            
-            public void checkPermission(Permission p) {
-            }
+		String msg = null;
+		InetAddress group = null;
+		int groupPort = Support_PortManager.getNextPortForUDP();
+		SocketAddress groupSockAddr = null;
+		SocketAddress groupSockAddr2 = null;
 
-            public void checkMulticast(InetAddress address) {
-                throw new SecurityException("not allowed");
-            }
-        }
+                Enumeration theInterfaces = NetworkInterface.getNetworkInterfaces();
 
-        String msg = null;
-        InetAddress group = null;
-        int groupPort = Support_PortManager.getNextPortForUDP();
-        SocketAddress groupSockAddr = null;
-        SocketAddress groupSockAddr2 = null;
-
-        try {
-            Enumeration theInterfaces = NetworkInterface.getNetworkInterfaces();
-
-            // first validate that we handle a null group ok
-            mss = new MulticastSocket(groupPort);
-            try {
-                mss.leaveGroup(null, null);
-                fail("Did not get exception when group was null");
-            } catch (IllegalArgumentException e) {
-            }
-
-            // now validate we get the expected error if the address specified
-            // is not a multicast group
-            try {
-                group = InetAddress.getByName("255.255.255.255");
-                groupSockAddr = new InetSocketAddress(group, groupPort);
-                mss.leaveGroup(groupSockAddr, null);
-                fail("Did not get exception when group is not a " +
-                        "multicast address");
-            } catch (IOException e) {
-            }
-
-            // now try to leave a group if we are not authorized
-            // set the security manager that will make the first address not
-            // visible
-            System.setSecurityManager(new mySecurityManager());
-            try {
-                group = InetAddress.getByName("224.0.0.3");
-                groupSockAddr = new InetSocketAddress(group, groupPort);
-                mss.leaveGroup(groupSockAddr, null);
-                fail("Did not get exception when joining group is " +
-                        "not allowed");
-            } catch (SecurityException e) {
-            }
-            System.setSecurityManager(null);
-
-            if (atLeastOneInterface) {
-
-                // now test that we can join and leave a group successfully
-                groupPort = Support_PortManager.getNextPortForUDP();
+                // first validate that we handle a null group ok
                 mss = new MulticastSocket(groupPort);
-                groupSockAddr = new InetSocketAddress(group, groupPort);
-                mss.joinGroup(groupSockAddr, null);
-                mss.leaveGroup(groupSockAddr, null);
                 try {
-                    mss.leaveGroup(groupSockAddr, null);
-                    fail(
-                            "Did not get exception when trying to leave " +
-                            "group that was allready left");
+                        mss.leaveGroup(null, null);
+                        fail("Did not get exception when group was null");
+                } catch (IllegalArgumentException e) {
+                }
+
+                // now validate we get the expected error if the address specified
+                // is not a multicast group
+                try {
+                        group = InetAddress.getByName("255.255.255.255");
+                        groupSockAddr = new InetSocketAddress(group, groupPort);
+                        mss.leaveGroup(groupSockAddr, null);
+                        fail("Did not get exception when group is not a multicast address");
                 } catch (IOException e) {
                 }
 
-                InetAddress group2 = InetAddress.getByName("224.0.0.4");
-                groupSockAddr2 = new InetSocketAddress(group2, groupPort);
-                mss.joinGroup(groupSockAddr, networkInterface1);
+                // now try to leave a group if we are not authorized
+                // set the security manager that will make the first address not
+                // visible
+                System.setSecurityManager(new mySecurityManager());
                 try {
-                    mss.leaveGroup(groupSockAddr2, networkInterface1);
-                    fail(
-                            "Did not get exception when trying to leave " +
-                            "group that was never joined");
-                } catch (IOException e) {
+                        group = InetAddress.getByName("224.0.0.3");
+                        groupSockAddr = new InetSocketAddress(group, groupPort);
+                        mss.leaveGroup(groupSockAddr, null);
+                        fail("Did not get exception when joining group is not allowed");
+                } catch (SecurityException e) {
+                }
+                System.setSecurityManager(null);
+
+                if (atLeastOneInterface) {
+
+                        // now test that we can join and leave a group successfully
+                        groupPort = Support_PortManager.getNextPortForUDP();
+                        mss = new MulticastSocket(groupPort);
+                        groupSockAddr = new InetSocketAddress(group, groupPort);
+                        mss.joinGroup(groupSockAddr, null);
+                        mss.leaveGroup(groupSockAddr, null);
+                        try {
+                                mss.leaveGroup(groupSockAddr, null);
+                                fail(
+                                                "Did not get exception when trying to leave group that was allready left");
+                        } catch (IOException e) {
+                        }
+
+                        InetAddress group2 = InetAddress.getByName("224.0.0.4");
+                        groupSockAddr2 = new InetSocketAddress(group2, groupPort);
+                        mss.joinGroup(groupSockAddr, networkInterface1);
+                        try {
+                                mss.leaveGroup(groupSockAddr2, networkInterface1);
+                                fail(
+                                                "Did not get exception when trying to leave group that was never joined");
+                        } catch (IOException e) {
+                        }
+
+                        mss.leaveGroup(groupSockAddr, networkInterface1);
+                        if (atLeastTwoInterfaces) {
+                                mss.joinGroup(groupSockAddr, networkInterface1);
+                                try {
+                                        mss.leaveGroup(groupSockAddr, networkInterface2);
+                                        fail(
+                                                        "Did not get exception when trying to leave group on wrong interface joined on ["
+                                                                        + networkInterface1
+                                                                        + "] left on ["
+                                                                        + networkInterface2 + "]");
+                                } catch (IOException e) {
+                                }
+                        }
                 }
 
-                mss.leaveGroup(groupSockAddr, networkInterface1);
-                if (atLeastTwoInterfaces) {
-                    mss.joinGroup(groupSockAddr, networkInterface1);
-                    try {
-                        mss.leaveGroup(groupSockAddr, networkInterface2);
-                        fail(
-                                "Did not get exception when trying to leave " +
-                                "group on wrong interface joined on ["
-                                        + networkInterface1
-                                        + "] left on ["
-                                        + networkInterface2 + "]");
-                    } catch (IOException e) {
-                    }
-                }
-            }
-        } catch (Exception e) {
-            fail("Exception during leaveGroup test: " + e.toString());
-        } finally {
-            System.setSecurityManager(null);
-        }
-    }
+                System.setSecurityManager(null);
+	}
 
-    /**
-     * @tests java.net.MulticastSocket#send(java.net.DatagramPacket, byte)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "send",
-        args = {java.net.DatagramPacket.class, byte.class}
-    )
-    public void test_sendLjava_net_DatagramPacketB() throws InterruptedException {
-        // Test for method void
-        // java.net.MulticastSocket.send(java.net.DatagramPacket, byte)
+	/**
+	 * @tests java.net.MulticastSocket#send(java.net.DatagramPacket, byte)
+	 */
+	public void test_sendLjava_net_DatagramPacketB() {
+		// Test for method void
+		// java.net.MulticastSocket.send(java.net.DatagramPacket, byte)
 
-        String msg = "Hello World";
-        InetAddress group = null;
-        int[] ports = Support_PortManager.getNextPortsForUDP(2);
-        int groupPort = ports[0];
+		String msg = "Hello World";
+		InetAddress group = null;
+		int[] ports = Support_PortManager.getNextPortsForUDP(2);
+		int groupPort = ports[0];
 
-        try {
-            group = InetAddress.getByName("224.0.0.3");
-            mss = new MulticastSocket(ports[1]);
-            server = new MulticastServer(group, groupPort);
-            server.start();
-            Thread.sleep(200);
-            DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg
-                    .length(), group, groupPort);
-            mss.send(sdp, (byte) 10);
-            Thread.sleep(1000);
-            ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
-        } catch (Exception e) {
-            handleException(e, SO_MULTICAST);
-            try {
-                mss.close();
-            } catch (Exception ex) {
-            }
-            
-            return;
-        }
-        
-        DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg
-                .length(), group, groupPort);
+		try {
+			group = InetAddress.getByName("224.0.0.3");
+			mss = new MulticastSocket(ports[1]);
+			server = new MulticastServer(group, groupPort);
+			server.start();
+			Thread.sleep(200);
+			DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg
+					.length(), group, groupPort);
+			mss.send(sdp, (byte) 10);
+			Thread.sleep(1000);
+			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
+		} catch (Exception e) {
+			handleException(e, SO_MULTICAST);
+			try {
+				mss.close();
+			} catch (Exception ex) {
+			}
+			;
+			return;
+		}
+		mss.close();
+		byte[] data = server.rdp.getData();
+		int length = server.rdp.getLength();
+		assertEquals("Failed to send data. Received " + length,
+                             msg, new String(data, 0, length));
+	}
 
-        
-        SecurityManager sm = new SecurityManager() {
+	/**
+	 * @tests java.net.MulticastSocket#setInterface(java.net.InetAddress)
+	 */
+	public void test_setInterfaceLjava_net_InetAddress() throws UnknownHostException {
+		// Test for method void
+		// java.net.MulticastSocket.setInterface(java.net.InetAddress)
+		// Note that the machine is not multi-homed
 
-            public void checkPermission(Permission perm) {
-            }
-            
-            public void checkConnect(String host,
-                    int port) {
-                throw new SecurityException();
-            }
-            
-            public void checkMulticast(InetAddress maddr) {
-                throw new SecurityException();
-            }
-        };
+		try {
+			mss = new MulticastSocket();
+			mss.setInterface(InetAddress.getLocalHost());
+			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST_INTERFACE);
+		} catch (Exception e) {
+			handleException(e, SO_MULTICAST_INTERFACE);
+			return;
+		}
+		try {
+			InetAddress theInterface = mss.getInterface();
+			// under IPV6 we are not guarrenteed to get the same address back as
+			// the address, all we should be guaranteed is that we get an
+			// address on the same interface
+			if (theInterface instanceof Inet6Address) {
+				assertTrue(
+						"Failed to return correct interface IPV6",
+						NetworkInterface
+								.getByInetAddress(mss.getInterface())
+								.equals(
+										NetworkInterface
+												.getByInetAddress(theInterface)));
+			} else {
+				assertTrue("Failed to return correct interface IPV4 got:"
+						+ mss.getInterface() + " excpeted: "
+						+ InetAddress.getLocalHost(), mss.getInterface()
+						.equals(InetAddress.getLocalHost()));
+			}
+			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
+		} catch (SocketException e) {
+			handleException(e, SO_MULTICAST);
+		}
 
-        SecurityManager oldSm = System.getSecurityManager();
-        System.setSecurityManager(sm);
-        try {
-            mss.send(sdp);
-            fail("SecurityException should be thrown.");
-        } catch (SecurityException e) {
-            // expected
-        } catch (SocketException e) {
-            fail("SocketException was thrown.");
-        } catch (IOException e) {
-            fail("IOException was thrown.");
-            e.printStackTrace();
-        } finally {
-            System.setSecurityManager(oldSm);
-        } 
-        
-        mss.close();
-        
-        try {
-            mss.send(sdp);
-            fail("IOException should be thrown.");
-        } catch(IOException ioe) {
-            //expected
-        }
+		// Regression test for Harmony-2410
+		try {
+			mss = new MulticastSocket();
+			mss.setInterface(InetAddress.getByName("224.0.0.5"));
+		} catch (SocketException se) {
+			// expected
+		} catch (IOException ioe) {
+			handleException(ioe, SO_MULTICAST_INTERFACE);
+			return;
+		}
+	}
 
-        DatagramPacket rdp = server.receive();
-        assertEquals("Failed to send data. Received " + rdp.getLength(), msg,
-                new String(rdp.getData(), 0, rdp.getLength()));
-    }
-
-    /**
-     * @tests java.net.MulticastSocket#setInterface(java.net.InetAddress)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setInterface",
-        args = {java.net.InetAddress.class}
-    )
-    public void test_setInterfaceLjava_net_InetAddress() {
-        // Test for method void
-        // java.net.MulticastSocket.setInterface(java.net.InetAddress)
-        // Note that the machine is not multi-homed
-
-        try {
-            mss = new MulticastSocket();
-            mss.setInterface(InetAddress.getLocalHost());
-            ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST_INTERFACE);
-        } catch (Exception e) {
-            //handleException(e, SO_MULTICAST_INTERFACE);
-            return;
-        }
-        try {
-            InetAddress theInterface = mss.getInterface();
-            // under IPV6 we are not guarrenteed to get the same address back as
-            // the address, all we should be guaranteed is that we get an
-            // address on the same interface
-            if (theInterface instanceof Inet6Address) {
-                assertTrue(
-                        "Failed to return correct interface IPV6",
-                        NetworkInterface
-                                .getByInetAddress(mss.getInterface())
-                                .equals(
-                                        NetworkInterface
-                                                .getByInetAddress(theInterface)));
-            } else {
-                assertTrue("Failed to return correct interface IPV4 got:"
-                        + mss.getInterface() + " excpeted: "
-                        + InetAddress.getLocalHost(), mss.getInterface()
-                        .equals(InetAddress.getLocalHost()));
-            }
-            ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
-        } catch (SocketException e) {
-            handleException(e, SO_MULTICAST);
-        } catch (UnknownHostException e) {
-            fail("Exception during setInterface test: " + e.toString());
-        }
-
-        // Regression test for Harmony-2410
-        try {
-            mss = new MulticastSocket();
-            mss.setInterface(InetAddress.getByName("224.0.0.5"));
-        } catch (UnknownHostException uhe) {
-            fail("Unable to get InetAddress by name from '224.0.0.5' addr: " 
-                    + uhe.toString());
-        } catch (SocketException se) {
-            // expected
-        } catch (IOException ioe) {
-            handleException(ioe, SO_MULTICAST_INTERFACE);
-            return;
-        }
-    }
-
-    /**
-     * @throws IOException 
-     * @throws InterruptedException 
-     * @tests java.net.MulticastSocket#setNetworkInterface(
-     *                                              java.net.NetworkInterface)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setNetworkInterface",
-        args = {java.net.NetworkInterface.class}
-    )
-    public void test_setNetworkInterfaceLjava_net_NetworkInterface() 
-                                    throws IOException, InterruptedException {
-        String msg = null;
-        InetAddress group = null;
-        int[] ports = Support_PortManager.getNextPortsForUDP(2);
-        int groupPort = ports[0];
-        int serverPort = ports[1];
-        if (atLeastOneInterface) {
+	/**
+	 * @throws IOException 
+	 * @throws InterruptedException 
+	 * @tests java.net.MulticastSocket#setNetworkInterface(java.net.NetworkInterface)
+	 */
+	public void test_setNetworkInterfaceLjava_net_NetworkInterface() throws IOException, InterruptedException {
+		String msg = null;
+		InetAddress group = null;
+		int[] ports = Support_PortManager.getNextPortsForUDP(2);
+		int groupPort = ports[0];
+		int serverPort = ports[1];
+		if (atLeastOneInterface) {
             // validate that null interface is handled ok
             mss = new MulticastSocket(groupPort);
 
             // this should through a socket exception to be compatible
             try {
                 mss.setNetworkInterface(null);
-                fail("No socket exception when we set then network " +
-                        "interface with NULL");
+                fail("No socket exception when we set then network interface with NULL");
             } catch (SocketException ex) {
             }
 
@@ -1122,9 +809,8 @@
             groupPort = Support_PortManager.getNextPortForUDP();
             mss = new MulticastSocket(groupPort);
             mss.setNetworkInterface(networkInterface1);
-            assertTrue(
-                    "Interface did not seem to be set by setNeworkInterface",
-                    networkInterface1.equals(mss.getNetworkInterface()));
+            assertEquals("Interface did not seem to be set by setNeworkInterface",
+                         networkInterface1, mss.getNetworkInterface());
 
             // set up the server and join the group
             group = InetAddress.getByName("224.0.0.3");
@@ -1133,8 +819,7 @@
             while (theInterfaces.hasMoreElements()) {
                 NetworkInterface thisInterface = (NetworkInterface) theInterfaces
                         .nextElement();
-                if (thisInterface.getInetAddresses() != null
-                        && thisInterface.getInetAddresses().hasMoreElements()) {
+                if (thisInterface.getInetAddresses().hasMoreElements()) {
                     if ((!((InetAddress) thisInterface.getInetAddresses()
                             .nextElement()).isLoopbackAddress())
                             &&
@@ -1163,95 +848,57 @@
                         DatagramPacket sdp = new DatagramPacket(theBytes,
                                 theBytes.length, group, serverPort);
                         mss.send(sdp);
-                        DatagramPacket rdp = server.receive();
-
-                        String receivedMessage = new String(rdp.getData(), 0, rdp.getLength());
-                        assertEquals("Group member did not recv data when send on "
-                                + "a specific interface: ", msg, receivedMessage);
-                        assertEquals("Datagram was not received as expected.",
-                                thisInterface, NetworkInterface.getByInetAddress(rdp.getAddress()));
-
+                        Thread.sleep(1000);
+                        String receivedMessage = new String(server.rdp
+                                .getData(), 0, server.rdp.getLength());
+                        assertEquals("Group member did not recv data sent on a specific interface",
+                                     msg, receivedMessage);
                         // stop the server
                         server.stopServer();
                     }
                 }
             }
         }
-    }
+	}
 
-    /**
-     * @tests java.net.MulticastSocket#setTimeToLive(int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setTimeToLive",
-        args = {int.class}
-    )
-    public void test_setTimeToLiveI() {
-        try {
-            mss = new MulticastSocket();
-            mss.setTimeToLive(120);
-            assertTrue("Returned incorrect 1st TTL: " + mss.getTimeToLive(),
-                    mss.getTimeToLive() == 120);
-            mss.setTimeToLive(220);
-            assertTrue("Returned incorrect 2nd TTL: " + mss.getTimeToLive(),
-                    mss.getTimeToLive() == 220);
-            mss.close();
-            try {
-                mss.setTimeToLive(1);
-                fail("IOException was not thrown.");
-            }catch(IOException ioe) {
-                //expected
-            } 
-            
-            ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
-        } catch (Exception e) {
-            handleException(e, SO_MULTICAST);
-        }
-    }
+	/**
+	 * @tests java.net.MulticastSocket#setTimeToLive(int)
+	 */
+	public void test_setTimeToLiveI() {
+		try {
+			mss = new MulticastSocket();
+			mss.setTimeToLive(120);
+			assertEquals("Returned incorrect 1st TTL",
+                                     120, mss.getTimeToLive());
+			mss.setTimeToLive(220);
+			assertEquals("Returned incorrect 2nd TTL",
+                                     220, mss.getTimeToLive());
+			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
+		} catch (Exception e) {
+			handleException(e, SO_MULTICAST);
+		}
+	}
 
-    /**
-     * @tests java.net.MulticastSocket#setTTL(byte)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setTTL",
-        args = {byte.class}
-    )
-    public void test_setTTLB() {
-        // Test for method void java.net.MulticastSocket.setTTL(byte)
-        try {
-            mss = new MulticastSocket();
-            mss.setTTL((byte) 120);
-            assertTrue("Failed to set TTL: " + mss.getTTL(),
-                    mss.getTTL() == 120);
-            
-            mss.close();
-            try {
-                mss.setTTL((byte) 1);
-                fail("IOException was not thrown.");
-            } catch(IOException ioe) {
-                //expected
-            } 
-            ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
-        } catch (Exception e) {
-            handleException(e, SO_MULTICAST);
-        }
-    }
+	/**
+	 * @tests java.net.MulticastSocket#setTTL(byte)
+	 */
+	public void test_setTTLB() {
+		// Test for method void java.net.MulticastSocket.setTTL(byte)
+		try {
+			mss = new MulticastSocket();
+			mss.setTTL((byte) 120);
+			assertEquals("Failed to set TTL", 120, mss.getTTL());
+			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
+		} catch (Exception e) {
+			handleException(e, SO_MULTICAST);
+		}
+	}
 
-    /**
-     * @tests java.net.MulticastSocket#MulticastSocket(java.net.SocketAddress)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "MulticastSocket",
-        args = {java.net.SocketAddress.class}
-    )
-    public void test_ConstructorLjava_net_SocketAddress() throws Exception {    
-        MulticastSocket ms = new MulticastSocket((SocketAddress) null);
+	/**
+	 * @tests java.net.MulticastSocket#MulticastSocket(java.net.SocketAddress)
+	 */
+	public void test_ConstructorLjava_net_SocketAddress() throws Exception {	
+		MulticastSocket ms = new MulticastSocket((SocketAddress) null);
         assertTrue("should not be bound", !ms.isBound() && !ms.isClosed()
                 && !ms.isConnected());
         ms.bind(new InetSocketAddress(InetAddress.getLocalHost(),
@@ -1285,109 +932,48 @@
         InetSocketAddress addr = new InetSocketAddress("0.0.0.0", 0);
         MulticastSocket s = new MulticastSocket(addr);
         assertTrue(s.getReuseAddress()); 
-        
-        InetSocketAddress isa = new InetSocketAddress(InetAddress
-                .getLocalHost(), Support_PortManager.getNextPortForUDP());
-        
-        SecurityManager sm = new SecurityManager() {
+	}
 
-            public void checkPermission(Permission perm) {
-            }
-            
-            public void checkListen(int port) {
-                throw new SecurityException();
-            }
-        };
-        
-        SecurityManager oldSm = System.getSecurityManager();
-        System.setSecurityManager(sm);
-        try {
-            new MulticastSocket(isa);
-            fail("SecurityException should be thrown.");
-        } catch (SecurityException e) {
-            // expected
-        } catch (SocketException e) {
-            fail("SocketException was thrown.");
-        } catch (IOException e) {
-            fail("IOException was thrown.");
-            e.printStackTrace();
-        } finally {
-            System.setSecurityManager(oldSm);
-        }  
-    }
+	/**
+	 * @tests java.net.MulticastSocket#getLoopbackMode()
+	 */
+	public void test_getLoopbackMode() {
+		try {
+			MulticastSocket ms = new MulticastSocket((SocketAddress) null);
+			assertTrue("should not be bound", !ms.isBound() && !ms.isClosed()
+					&& !ms.isConnected());
+			ms.getLoopbackMode();
+			assertTrue("should not be bound", !ms.isBound() && !ms.isClosed()
+					&& !ms.isConnected());
+			ms.close();
+			assertTrue("should be closed", ms.isClosed());
+			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_USELOOPBACK);
+		} catch (IOException e) {
+			handleException(e, SO_USELOOPBACK);
+		}
+	}
 
-    /**
-     * @tests java.net.MulticastSocket#getLoopbackMode()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getLoopbackMode",
-        args = {}
-    )
-    public void test_getLoopbackMode() {
-        try {
-            MulticastSocket ms = new MulticastSocket((SocketAddress) null);
-            assertTrue("should not be bound", !ms.isBound() && !ms.isClosed()
-                    && !ms.isConnected());
-            ms.getLoopbackMode();
-            assertTrue("should not be bound", !ms.isBound() && !ms.isClosed()
-                    && !ms.isConnected());
-            ms.close();
-            assertTrue("should be closed", ms.isClosed());
-            try {
-                ms.getLoopbackMode();
-                fail("SocketException was not thrown.");
-            } catch(SocketException ioe) {
-                //expected
-            }
-            ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_USELOOPBACK);
-        } catch (IOException e) {
-            handleException(e, SO_USELOOPBACK);
-        }
-    }
-
-    /**
-     * @tests java.net.MulticastSocket#setLoopbackMode(boolean)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setLoopbackMode",
-        args = {boolean.class}
-    )
-    public void test_setLoopbackModeZ() {
-        try {
-            MulticastSocket ms = new MulticastSocket();
-            ms.setLoopbackMode(true);
-            assertTrue("loopback should be true", ms.getLoopbackMode());
-            ms.setLoopbackMode(false);
-            assertTrue("loopback should be false", !ms.getLoopbackMode());
-            ms.close();
-            assertTrue("should be closed", ms.isClosed());
-            
-            try {
-                ms.setLoopbackMode(true);
-                fail("SocketException was not thrown.");
-            } catch(SocketException se) {
-                //expected
-            }
-            
-            ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_USELOOPBACK);
-        } catch (IOException e) {
-            handleException(e, SO_USELOOPBACK);
-        }
-    }
+	/**
+	 * @tests java.net.MulticastSocket#setLoopbackMode(boolean)
+	 */
+	public void test_setLoopbackModeZ() {
+		try {
+			MulticastSocket ms = new MulticastSocket();
+			ms.setLoopbackMode(true);
+			assertTrue("loopback should be true", ms.getLoopbackMode());
+			ms.setLoopbackMode(false);
+			assertTrue("loopback should be false", !ms.getLoopbackMode());
+			ms.close();
+			assertTrue("should be closed", ms.isClosed());
+			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_USELOOPBACK);
+		} catch (IOException e) {
+			handleException(e, SO_USELOOPBACK);
+		}
+	}
     
     /**
      * @tests java.net.MulticastSocket#setLoopbackMode(boolean)
      */
-    @TestTargetNew(
-        level = TestLevel.ADDITIONAL,
-        notes = "SocketException checking missed",
-        method = "setLoopbackMode",
-        args = {boolean.class}
-    )
     public void test_setLoopbackModeSendReceive() throws IOException{
         final String ADDRESS = "224.1.2.3";
         final int PORT = Support_PortManager.getNextPortForUDP();
@@ -1418,120 +1004,99 @@
             String recvMessage = new String(recvData, 0, recvDatagram
                     .getLength());
             assertEquals(message, recvMessage);
-        } finally {
+        }finally {
             if (socket != null)
                 socket.close();
         }
     }
     
     
-    /**
-     * @tests java.net.MulticastSocket#setReuseAddress(boolean)
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "SocketException checking missesd. Method inherited from " +
-                "class java.net.DatagramSocket",
-        method = "setReuseAddress",
-        args = {boolean.class}
-    )
-    public void test_setReuseAddressZ() {
-        try {
-            // test case were we set it to false
-            MulticastSocket theSocket1 = null;
-            MulticastSocket theSocket2 = null;
-            try {
-                InetSocketAddress theAddress = new InetSocketAddress(
-                        InetAddress.getLocalHost(), Support_PortManager
-                                .getNextPortForUDP());
-                theSocket1 = new MulticastSocket(null);
-                theSocket2 = new MulticastSocket(null);
-                theSocket1.setReuseAddress(false);
-                theSocket2.setReuseAddress(false);
-                theSocket1.bind(theAddress);
-                theSocket2.bind(theAddress);
-                fail(
-                        "No exception when trying to connect to do " +
-                        "duplicate socket bind with re-useaddr set to false");
-            } catch (BindException e) {
+	/**
+	 * @tests java.net.MulticastSocket#setReuseAddress(boolean)
+	 */
+	public void test_setReuseAddressZ() throws Exception {
+		try {
+			// test case were we set it to false
+			MulticastSocket theSocket1 = null;
+			MulticastSocket theSocket2 = null;
+			try {
+				InetSocketAddress theAddress = new InetSocketAddress(
+						InetAddress.getLocalHost(), Support_PortManager
+								.getNextPortForUDP());
+				theSocket1 = new MulticastSocket(null);
+				theSocket2 = new MulticastSocket(null);
+				theSocket1.setReuseAddress(false);
+				theSocket2.setReuseAddress(false);
+				theSocket1.bind(theAddress);
+				theSocket2.bind(theAddress);
+				fail(
+						"No exception when trying to connect to do duplicate socket bind with re-useaddr set to false");
+			} catch (BindException e) {
 
-            }
-            if (theSocket1 != null)
-                theSocket1.close();
-            if (theSocket2 != null)
-                theSocket2.close();
+			}
+			if (theSocket1 != null)
+				theSocket1.close();
+			if (theSocket2 != null)
+				theSocket2.close();
 
-            // test case were we set it to true
-            try {
-                InetSocketAddress theAddress = new InetSocketAddress(
-                        InetAddress.getLocalHost(), Support_PortManager
-                                .getNextPortForUDP());
-                theSocket1 = new MulticastSocket(null);
-                theSocket2 = new MulticastSocket(null);
-                theSocket1.setReuseAddress(true);
-                theSocket2.setReuseAddress(true);
-                theSocket1.bind(theAddress);
-                theSocket2.bind(theAddress);
-            } catch (Exception e) {
-                fail(
-                        "unexpected exception when trying to connect " +
-                        "to do duplicate socket bind with re-useaddr set " +
-                        "to true");
-            }
-            if (theSocket1 != null)
-                theSocket1.close();
-            if (theSocket2 != null)
-                theSocket2.close();
+			// test case were we set it to true
+                        InetSocketAddress theAddress = new InetSocketAddress(
+                                        InetAddress.getLocalHost(), Support_PortManager
+                                                        .getNextPortForUDP());
+                        theSocket1 = new MulticastSocket(null);
+                        theSocket2 = new MulticastSocket(null);
+                        theSocket1.setReuseAddress(true);
+                        theSocket2.setReuseAddress(true);
+                        theSocket1.bind(theAddress);
+                        theSocket2.bind(theAddress);
 
-            // test the default case which we expect to be the same on all
-            // platforms
-            try {
-                InetSocketAddress theAddress = new InetSocketAddress(
-                        InetAddress.getLocalHost(), Support_PortManager
-                                .getNextPortForUDP());
-                theSocket1 = new MulticastSocket(null);
-                theSocket2 = new MulticastSocket(null);
-                theSocket1.bind(theAddress);
-                theSocket2.bind(theAddress);
-            } catch (BindException e) {
-                fail(
-                        "unexpected exception when trying to connect to do " +
-                        "duplicate socket bind with re-useaddr left as default");
-            }
-            if (theSocket1 != null)
-                theSocket1.close();
-            if (theSocket2 != null)
-                theSocket2.close();
-            ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_REUSEADDR);
-        } catch (Exception e) {
-            handleException(e, SO_REUSEADDR);
-        }
-    }
+                        if (theSocket1 != null)
+				theSocket1.close();
+			if (theSocket2 != null)
+				theSocket2.close();
 
-    /**
-     * Sets up the fixture, for example, open a network connection. This method
-     * is called before a test is executed.
-     */
-    protected void setUp() {
+			// test the default case which we expect to be
+			// the same on all platforms
+                        theAddress =
+                            new InetSocketAddress(
+                                    InetAddress.getLocalHost(),
+                                    Support_PortManager.getNextPortForUDP());
+                        theSocket1 = new MulticastSocket(null);
+                        theSocket2 = new MulticastSocket(null);
+                        theSocket1.bind(theAddress);
+                        theSocket2.bind(theAddress);
+			if (theSocket1 != null)
+				theSocket1.close();
+			if (theSocket2 != null)
+				theSocket2.close();
+			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_REUSEADDR);
+		} catch (Exception e) {
+			handleException(e, SO_REUSEADDR);
+		}
+	}
 
-        Enumeration theInterfaces = null;
-        try {
-            theInterfaces = NetworkInterface.getNetworkInterfaces();
-        } catch (Exception e) {
-        }
+	/**
+	 * Sets up the fixture, for example, open a network connection. This method
+	 * is called before a test is executed.
+	 */
+	protected void setUp() {
 
-        // only consider interfaces that have addresses associated with them.
-        // Otherwise tests don't work so well
-        if (theInterfaces != null) {
+		Enumeration theInterfaces = null;
+		try {
+			theInterfaces = NetworkInterface.getNetworkInterfaces();
+		} catch (Exception e) {
+		}
 
-            atLeastOneInterface = false;
-            while (theInterfaces.hasMoreElements()
+		// only consider interfaces that have addresses associated with them.
+		// Otherwise tests don't work so well
+		if (theInterfaces != null) {
+
+			atLeastOneInterface = false;
+			while (theInterfaces.hasMoreElements()
                     && (atLeastOneInterface == false)) {
                 networkInterface1 = (NetworkInterface) theInterfaces
                         .nextElement();
-                if ((networkInterface1.getInetAddresses() != null)
-                        && networkInterface1.getInetAddresses()
-                                .hasMoreElements() &&
+                if (networkInterface1.getInetAddresses().hasMoreElements() &&
                         // we only want real interfaces
                         (Support_NetworkInterface
                                 .useInterface(networkInterface1) == true)) {
@@ -1539,15 +1104,14 @@
                 }
             }
 
-            atLeastTwoInterfaces = false;
-            if (theInterfaces.hasMoreElements()) {
+			atLeastTwoInterfaces = false;
+			if (theInterfaces.hasMoreElements()) {
                 while (theInterfaces.hasMoreElements()
                         && (atLeastTwoInterfaces == false)) {
                     networkInterface2 = (NetworkInterface) theInterfaces
                             .nextElement();
-                    if ((networkInterface2.getInetAddresses() != null)
-                            && networkInterface2.getInetAddresses()
-                                    .hasMoreElements() &&
+                    if (networkInterface2.getInetAddresses().hasMoreElements()
+                            &&
                             // we only want real interfaces
                             (Support_NetworkInterface
                                     .useInterface(networkInterface2) == true)) {
@@ -1556,44 +1120,44 @@
                 }
             }
 
-            Enumeration addresses;
+			Enumeration addresses;
 
-            // first the first interface that supports IPV6 if one exists
-            try {
-                theInterfaces = NetworkInterface.getNetworkInterfaces();
-            } catch (Exception e) {
-            }
-            boolean found = false;
-            while (theInterfaces.hasMoreElements() && !found) {
-                NetworkInterface nextInterface = (NetworkInterface) theInterfaces
-                        .nextElement();
-                addresses = nextInterface.getInetAddresses();
-                if (addresses != null) {
-                    while (addresses.hasMoreElements()) {
-                        InetAddress nextAddress = (InetAddress) addresses
-                                .nextElement();
-                        if (nextAddress instanceof Inet6Address) {
-                            IPV6networkInterface1 = nextInterface;
-                            found = true;
-                            break;
-                        }
-                    }
-                }
-            }
-        }
-    }
+			// first the first interface that supports IPV6 if one exists
+			try {
+				theInterfaces = NetworkInterface.getNetworkInterfaces();
+			} catch (Exception e) {
+			}
+			boolean found = false;
+			while (theInterfaces.hasMoreElements() && !found) {
+				NetworkInterface nextInterface = (NetworkInterface) theInterfaces
+						.nextElement();
+				addresses = nextInterface.getInetAddresses();
+				if (addresses.hasMoreElements()) {
+					while (addresses.hasMoreElements()) {
+						InetAddress nextAddress = (InetAddress) addresses
+								.nextElement();
+						if (nextAddress instanceof Inet6Address) {
+							IPV6networkInterface1 = nextInterface;
+							found = true;
+							break;
+						}
+					}
+				}
+			}
+		}
+	}
 
-    /**
-     * Tears down the fixture, for example, close a network connection. This
-     * method is called after a test is executed.
-     */
-    protected void tearDown() throws InterruptedException {
+	/**
+	 * Tears down the fixture, for example, close a network connection. This
+	 * method is called after a test is executed.
+	 */
+	protected void tearDown() {
 
-        if (t != null)
-            t.interrupt();
-        if (mss != null)
-            mss.close();
-        if (server != null)
-            server.stopServer();
-    }
+		if (t != null)
+			t.interrupt();
+		if (mss != null)
+			mss.close();
+		if (server != null)
+			server.stopServer();
+	}
 }