changeset 58377:29f4b46a1680

8059309: network tests fail with "java.net.SocketException: Couldn't obtain phys addr" when run as "root" Summary: The solaris specific code is changed to use the fallback mechanism if the DLPI interface returns an error indicating that the operation is unsupported. In addition, NetworkInterface::getHardwareAddress is changed to always return null for the loopback interface. Reviewed-by: alanb
author dfuchs
date Thu, 12 Mar 2020 18:31:49 +0000
parents 61f6c19d1a56
children 222127a06550
files src/java.base/share/classes/java/net/NetworkInterface.java src/java.base/unix/native/libnet/NetworkInterface.c test/jdk/java/net/NetworkInterface/NullMacAddress.java
diffstat 3 files changed, 96 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/net/NetworkInterface.java	Thu Mar 12 18:50:18 2020 +0100
+++ b/src/java.base/share/classes/java/net/NetworkInterface.java	Thu Mar 12 18:31:49 2020 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -523,6 +523,9 @@
                 }
             }
         }
+        if (isLoopback0(name, index)) {
+            return null;
+        }
         for (InetAddress addr : addrs) {
             if (addr instanceof Inet4Address) {
                 return getMacAddr0(((Inet4Address)addr).getAddress(), name, index);
--- a/src/java.base/unix/native/libnet/NetworkInterface.c	Thu Mar 12 18:50:18 2020 +0100
+++ b/src/java.base/unix/native/libnet/NetworkInterface.c	Thu Mar 12 18:31:49 2020 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1884,6 +1884,7 @@
     int fd;
     dl_phys_addr_req_t dlpareq;
     dl_phys_addr_ack_t *dlpaack;
+    dl_error_ack_t     *dlerack;
     struct strbuf msg;
     char buf[128];
     int flags = 0;
@@ -1920,6 +1921,19 @@
         return -1;
     }
 
+    if (dlpaack->dl_primitive == DL_ERROR_ACK) {
+        dlerack = (dl_error_ack_t *)buf;
+        if (dlerack->dl_error_primitive != DL_PHYS_ADDR_REQ) {
+            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                           "Couldn't obtain physical address\n");
+            return -1;
+        }
+        if (dlerack->dl_errno == DL_UNSUPPORTED) {
+            // fallback to lookup in the ARP table
+            return 0;
+        }
+    }
+
     if (msg.len < DL_PHYS_ADDR_ACK_SIZE || dlpaack->dl_primitive != DL_PHYS_ADDR_ACK) {
         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                         "Couldn't obtain phys addr\n");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/NetworkInterface/NullMacAddress.java	Thu Mar 12 18:31:49 2020 +0000
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 8059309
+ * @summary Test that querrying the mac address of the loopback interface
+ *          returns null and doesn't throw a SocketException.
+ * @library /test/lib
+ * @run testng/othervm NullMacAddress
+ * @run testng/othervm -Djava.net.preferIPv6Addresses=true NullMacAddress
+ * @run testng/othervm -Djava.net.preferIPv4Stack=true NullMacAddress
+ */
+
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+import java.io.UncheckedIOException;
+import java.math.BigInteger;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.Locale;
+
+import jdk.test.lib.net.IPSupport;
+
+public class NullMacAddress {
+
+    @BeforeTest
+    void setup() {
+        IPSupport.throwSkippedExceptionIfNonOperational();
+    }
+
+    @Test
+    public void testNetworkInterfaces() throws SocketException {
+        NetworkInterface.networkInterfaces().forEach(this::testMacAddress);
+    }
+
+    private void testMacAddress(NetworkInterface ni) {
+        try {
+            var name = ni.getDisplayName();
+            System.out.println("Testing: " + name);
+            var loopback = ni.isLoopback();
+            var macAddress = ni.getHardwareAddress();
+            var hdr = macAddress == null ? "null"
+                    : "0x" + new BigInteger(1, macAddress)
+                    .toString(16).toUpperCase(Locale.ROOT);
+            System.out.println("   MAC address: " + hdr + (loopback ? " (loopback)" : ""));
+            if (loopback) {
+                assertNull(macAddress, "Loopback interface \""
+                        + name + "\" doesn't have a null MAC Address");
+            }
+        } catch (SocketException ex) {
+            throw new UncheckedIOException(ex);
+        }
+    }
+ }
+