Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8021372

NetworkInterface.getNetworkInterfaces() returns duplicate hardware address

    XMLWordPrintable

    Details

    • Subcomponent:
    • Resolved In Build:
      b108
    • OS:
      windows_2008
    • Verification:
      Verified

      Backports

        Description

        FULL PRODUCT VERSION :
        java version " 1.6.0_26 "
        Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
        Java HotSpot(TM) Server VM (build 20.1-b02, mixed mode)

        ADDITIONAL OS VERSION INFORMATION :
        Windows Server 2008 R2

        EXTRA RELEVANT SYSTEM CONFIGURATION :
        the OS is hosted in a VM

        A DESCRIPTION OF THE PROBLEM :
        MAC Addresses of the network interfaces in the VM is retrieved by calling the following method NetworkInterface.getNetworkInterface().getHardwareAddress():

        The Physical machine has two network adapters. and therefore upon executing " ipconfig /all " command in the windows command prompt, there are two network adapters that can be observed with distinct IP Address and Physical Address.

        however, upon executing the above code at the problematic VMs, the system out shows similar Mac Address or Hardware Address for the two network adapters is returned, but the distinct IP Addresses for each network adapters are correctly returned.

        The behavior is observed in 3 out of 4 VMs, but only 1 VM behaves as expected i.e. the MAC Address is returned correctly.
        Each VM resides on a separate physical machine.

        All of the 4 VMs have the same network setup. and there is no change to the system or OS patches that is related to networking.

        Noted that this is similar to the following cases, but please kindly relook into the matters:
        1. JDK-6709430 : Unable to detect MAC address in Windows Vista
        2. JDK-6763420 : NetworkInterface.getNetworkInterfaces() returns duplicate

        REGRESSION. Last worked in version 6u43

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        Refer to the Description above.

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        The MAC Address or hardware address of the network adapter is returned correctly, according to that returned upon executing " ipconfig /all " command in Windows Command Prompt.
        ACTUAL -
        Refer to Description above.

        ERROR MESSAGES/STACK TRACES THAT OCCUR :
        Refer to Description above.

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        ---------- BEGIN SOURCE ----------
        package com.isprint.am.util;

        import java.io.IOException;
        import java.io.InputStream;
        import java.lang.reflect.Method;
        import java.net.InetAddress;
        import java.net.NetworkInterface;
        import java.net.SocketException;
        import java.util.ArrayList;
        import java.util.Enumeration;
        import java.util.HashMap;
        import java.util.Map;

        /**
         *
         */
        public class NetUtil {
            
            /** Utility class has no object instance */
            private NetUtil() {
            }
            
            /**
             * Execute the 'hostname' command to get local host name; this is more reliable than the host name from the network interfaces
             * @return
             * @throws IOException
             */
            public static String getExecHostName() throws IOException {
                Process proc = Runtime.getRuntime().exec( " hostname " );
                if(proc!=null) {
                    StringBuffer s = new StringBuffer();
                    byte[] b = new byte[256];
                    int k;
                    InputStream in = proc.getInputStream();
                    while((k=in.read(b))>-1) {
                        s.append(new String(b, 0, k));
                    }
                    k = s.indexOf( " \r
         " );
                    if(k<0) k = s.indexOf( "
         " );
                    if(k<0) k = s.length();
                    return s.substring(0, k);
                }
                return null;
            }

            /**
             * Only avail in JRE1.6 so we test with reflection
             * @param ni
             * @return
             */
            public static byte[] getHardwareAddrIfAvail(NetworkInterface ni) {
                try {
                    Method meth = ni.getClass().getDeclaredMethod( " getHardwareAddress " , new Class[0]);
                    byte[] mac = (byte[])meth.invoke(ni, new Object[0]);
                    return mac;
                } catch (NoSuchMethodException e) {
                    //jre 1.5 and below; ignore
                    return new byte[0];
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            }
            
            public static void main(String[] args) throws IOException {
            Enumeration nis = NetworkInterface.getNetworkInterfaces();
            System.out.println( "
        Hostname: " +getExecHostName()+ "
         " );
            while (nis.hasMoreElements()) {
            System.out.println( " ********************************** " );
            NetworkInterface ni = (NetworkInterface)nis.nextElement();
            System.out.println( " NetworkInterface displayName= " + ni.getDisplayName()+ " name= " +ni.getName()+'
        ');
                    Enumeration addrs = ni.getInetAddresses();
        while (addrs.hasMoreElements()) {
        InetAddress addr = (InetAddress) addrs.nextElement();
        System.out.println( " canonicalHostName= "
        + addr.getCanonicalHostName() + " hostName= "
        + addr.getHostName() + " hostAddr= "
        + addr.getHostAddress() + " , loopback= "
        + addr.isLoopbackAddress() + " linkLocal= "
        + addr.isLinkLocalAddress() + '
        ');
        byte[] macAddress = getHardwareAddrIfAvail(ni);
        //System.out.println( " macAddress - getHardwareAddress - reflection: " +EncodingUtil.hexBinEncodeAsString(macAddress).toString());
        //System.out.println( " macAddress - getHardwareAddress - method: " +EncodingUtil.hexBinEncodeAsString(ni.getHardwareAddress()).toString());
        byte[] mac = ni.getHardwareAddress();
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < mac.length; i++) {
                    sb.append(String.format( " %02X%s " , mac[i], (i < mac.length - 1) ? " - " : " " ));
                }
                System.out.println( " macAddress - getHardwareAddress - method - other format: " +sb.toString());

        }
            }
            }
        }

        ---------- END SOURCE ----------
        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        For the affected VMs, at the point of detection of the MAC Address or hardware address of the machine, the second network adapter is disabled.
        It is then enabled back after the MAC Address detection is not required anymore.

          Attachments

            Issue Links

              Activity

                People

                Assignee:
                msheppar Mark Sheppard
                Reporter:
                webbuggrp Webbug Group
                Votes:
                0 Vote for this issue
                Watchers:
                5 Start watching this issue

                  Dates

                  Created:
                  Updated:
                  Resolved: