Merge "Fix NetworkInterface#getHardwareAddress corner case"
diff --git a/luni/src/test/java/libcore/java/net/NetworkInterfaceTest.java b/luni/src/test/java/libcore/java/net/NetworkInterfaceTest.java
index 73cb7ac..6ddb483 100644
--- a/luni/src/test/java/libcore/java/net/NetworkInterfaceTest.java
+++ b/luni/src/test/java/libcore/java/net/NetworkInterfaceTest.java
@@ -17,6 +17,7 @@
package libcore.java.net;
import junit.framework.TestCase;
+import java.lang.reflect.Field;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
@@ -146,6 +147,48 @@
}
}
+ // b/28903817
+ public void testInterfaceRemoval() throws Exception {
+ NetworkInterface lo = NetworkInterface.getByName("lo");
+
+ // Simulate interface removal by changing it's name to unused value.
+ // This works only because getHardwareAddress (and others) is using name to fetch
+ // the NI data. If this changes, this test needs an update.
+ Field nameField = NetworkInterface.class.getDeclaredField("name");
+ nameField.setAccessible(true);
+ nameField.set(lo, "noSuchInterface");
+
+ try {
+ lo.getHardwareAddress();
+ fail();
+ } catch(SocketException expected) {}
+
+ try {
+ lo.getMTU();
+ fail();
+ } catch(SocketException expected) {}
+
+ try {
+ lo.isLoopback();
+ fail();
+ } catch(SocketException expected) {}
+
+ try {
+ lo.isUp();
+ fail();
+ } catch(SocketException expected) {}
+
+ try {
+ lo.isPointToPoint();
+ fail();
+ } catch(SocketException expected) {}
+
+ try {
+ lo.supportsMulticast();
+ fail();
+ } catch(SocketException expected) {}
+ }
+
// Is ifName a name of a Ethernet device?
private static Pattern ethernetNamePattern = Pattern.compile("^(eth|wlan)[0-9]+$");
private static boolean isEthernet(String ifName) throws Exception {
diff --git a/ojluni/src/main/java/java/net/NetworkInterface.java b/ojluni/src/main/java/java/net/NetworkInterface.java
index 3ea67be..ac39d2a 100755
--- a/ojluni/src/main/java/java/net/NetworkInterface.java
+++ b/ojluni/src/main/java/java/net/NetworkInterface.java
@@ -439,7 +439,13 @@
* @since 1.6
*/
public byte[] getHardwareAddress() throws SocketException {
- return (hardwareAddr != null) ? hardwareAddr.clone() : null;
+ // Android chage - do not use the cached address, fetch
+ // the object again. NI might not be valid anymore.
+ NetworkInterface ni = getByName0(name);
+ if (ni == null) {
+ throw new SocketException("NetworkInterface doesn't exist anymore");
+ }
+ return ni.hardwareAddr;
}
/**