This is an automated email from the ASF dual-hosted git repository.

rohit pushed a commit to branch 4.19
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/4.19 by this push:
     new b23ceefc7ea utils: cleanup MacAddress and MacAddressTest (#8988)
b23ceefc7ea is described below

commit b23ceefc7eabbc0bab85c85ffd7d4fdcbdc4c7b8
Author: Rohit Yadav <rohit.ya...@shapeblue.com>
AuthorDate: Mon Apr 29 13:42:31 2024 +0530

    utils: cleanup MacAddress and MacAddressTest (#8988)
    
    * utils: cleanup MacAddress and MacAddressTest
    
    Cleanup old mac address handling code to use JDK11 lib instead of hacks.
    Also really strange to see some basic string parsing code was written by
    hand, replaced with Long.parseValue(str, 16) to convert hex string to
    long.
    
    Signed-off-by: Rohit Yadav <rohit.ya...@shapeblue.com>
    
    * address review comments
    
    Signed-off-by: Rohit Yadav <rohit.ya...@shapeblue.com>
    
    ---------
    
    Signed-off-by: Rohit Yadav <rohit.ya...@shapeblue.com>
---
 .../main/java/com/cloud/utils/net/MacAddress.java  | 233 +++------------------
 .../java/com/cloud/utils/net/MacAddressTest.java   |  14 +-
 2 files changed, 40 insertions(+), 207 deletions(-)

diff --git a/utils/src/main/java/com/cloud/utils/net/MacAddress.java 
b/utils/src/main/java/com/cloud/utils/net/MacAddress.java
index d7ac9e39e7f..76f3f6c24ac 100644
--- a/utils/src/main/java/com/cloud/utils/net/MacAddress.java
+++ b/utils/src/main/java/com/cloud/utils/net/MacAddress.java
@@ -19,25 +19,19 @@
 
 package com.cloud.utils.net;
 
-import static com.cloud.utils.AutoCloseableUtil.closeAutoCloseable;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
 import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
 import java.net.UnknownHostException;
+import java.util.Collections;
 import java.util.Formatter;
-
-import org.apache.log4j.Logger;
+import java.util.List;
 
 /**
  * This class retrieves the (first) MAC address for the machine is it is 
loaded on and stores it statically for retrieval.
  * It can also be used for formatting MAC addresses.
- * copied fnd addpeted rom the public domain utility from John Burkard.
  **/
 public class MacAddress {
-    private static final Logger s_logger = Logger.getLogger(MacAddress.class);
     private long _addr = 0;
 
     protected MacAddress() {
@@ -75,213 +69,52 @@ public class MacAddress {
         return toString(":");
     }
 
-    private static MacAddress s_address;
-    static {
-        String macAddress = null;
-
-        Process p = null;
-        BufferedReader in = null;
+    private static MacAddress macAddress;
 
+    static {
+        String macString = null;
         try {
-            String osname = System.getProperty("os.name");
-
-            if (osname.startsWith("Windows")) {
-                p = Runtime.getRuntime().exec(new String[] {"ipconfig", 
"/all"}, null);
-            } else if (osname.startsWith("Solaris") || 
osname.startsWith("SunOS")) {
-                // Solaris code must appear before the generic code
-                String hostName = MacAddress.getFirstLineOfCommand(new 
String[] {"uname", "-n"});
-                if (hostName != null) {
-                    p = Runtime.getRuntime().exec(new String[] 
{"/usr/sbin/arp", hostName}, null);
-                }
-            } else if (new File("/usr/sbin/lanscan").exists()) {
-                p = Runtime.getRuntime().exec(new String[] 
{"/usr/sbin/lanscan"}, null);
-            } else if (new File("/sbin/ifconfig").exists()) {
-                p = Runtime.getRuntime().exec(new String[] {"/sbin/ifconfig", 
"-a"}, null);
-            }
-
-            if (p != null) {
-                in = new BufferedReader(new 
InputStreamReader(p.getInputStream()), 128);
-                String l = null;
-                while ((l = in.readLine()) != null) {
-                    macAddress = MacAddress.parse(l);
-                    if (macAddress != null) {
-                        short parsedShortMacAddress = 
MacAddress.parseShort(macAddress);
-                        if (parsedShortMacAddress != 0xff && 
parsedShortMacAddress != 0x00)
-                            break;
+            final List<NetworkInterface> nics = 
Collections.list(NetworkInterface.getNetworkInterfaces());
+            Collections.reverse(nics);
+            for (final NetworkInterface nic : nics) {
+                final byte[] mac = nic.getHardwareAddress();
+                if (mac != null &&
+                        !nic.isVirtual() &&
+                        !nic.isLoopback() &&
+                        !nic.getName().startsWith("br") &&
+                        !nic.getName().startsWith("veth") &&
+                        !nic.getName().startsWith("vnet")) {
+                    StringBuilder macAddressBuilder = new StringBuilder();
+                    for (byte b : mac) {
+                        macAddressBuilder.append(String.format("%02X", b));
                     }
-                    macAddress = null;
+                    macString = macAddressBuilder.toString();
+                    break;
                 }
             }
-
-        } catch (SecurityException ex) {
-            s_logger.info("[ignored] security exception in static initializer 
of MacAddress", ex);
-        } catch (IOException ex) {
-            s_logger.info("[ignored] io exception in static initializer of 
MacAddress");
-        } finally {
-            if (p != null) {
-                closeAutoCloseable(in, "closing init process input stream");
-                closeAutoCloseable(p.getErrorStream(), "closing init process 
error output stream");
-                closeAutoCloseable(p.getOutputStream(), "closing init process 
std output stream");
-                p.destroy();
-            }
+        } catch (SocketException ignore) {
         }
 
-        long clockSeqAndNode = 0;
+        long macAddressLong = 0;
 
-        if (macAddress != null) {
-            if (macAddress.indexOf(':') != -1) {
-                clockSeqAndNode |= MacAddress.parseLong(macAddress);
-            } else if (macAddress.startsWith("0x")) {
-                clockSeqAndNode |= 
MacAddress.parseLong(macAddress.substring(2));
-            }
+        if (macString != null) {
+            macAddressLong = Long.parseLong(macString, 16);
         } else {
             try {
                 byte[] local = InetAddress.getLocalHost().getAddress();
-                clockSeqAndNode |= (local[0] << 24) & 0xFF000000L;
-                clockSeqAndNode |= (local[1] << 16) & 0xFF0000;
-                clockSeqAndNode |= (local[2] << 8) & 0xFF00;
-                clockSeqAndNode |= local[3] & 0xFF;
+                macAddressLong |= (local[0] << 24) & 0xFF000000L;
+                macAddressLong |= (local[1] << 16) & 0xFF0000;
+                macAddressLong |= (local[2] << 8) & 0xFF00;
+                macAddressLong |= local[3] & 0xFF;
             } catch (UnknownHostException ex) {
-                clockSeqAndNode |= (long)(Math.random() * 0x7FFFFFFF);
+                macAddressLong |= (long)(Math.random() * 0x7FFFFFFF);
             }
         }
 
-        s_address = new MacAddress(clockSeqAndNode);
+        MacAddress.macAddress = new MacAddress(macAddressLong);
     }
 
     public static MacAddress getMacAddress() {
-        return s_address;
-    }
-
-    private static String getFirstLineOfCommand(String[] commands) throws 
IOException {
-
-        Process p = null;
-        BufferedReader reader = null;
-
-        try {
-            p = Runtime.getRuntime().exec(commands);
-            reader = new BufferedReader(new 
InputStreamReader(p.getInputStream()), 128);
-
-            return reader.readLine();
-        } finally {
-            if (p != null) {
-                closeAutoCloseable(reader, "closing process input stream");
-                closeAutoCloseable(p.getErrorStream(), "closing process error 
output stream");
-                closeAutoCloseable(p.getOutputStream(), "closing process std 
output stream");
-                p.destroy();
-            }
-        }
-
-    }
-
-    /**
-     * The MAC address parser attempts to find the following patterns:
-     * <ul>
-     * <li>.{1,2}:.{1,2}:.{1,2}:.{1,2}:.{1,2}:.{1,2}</li>
-     * <li>.{1,2}-.{1,2}-.{1,2}-.{1,2}-.{1,2}-.{1,2}</li>
-     * </ul>
-     *
-     * This is copied from the author below.  The author encouraged copying
-     * it.
-     *
-     */
-    static String parse(String in) {
-
-        // lanscan
-
-        int hexStart = in.indexOf("0x");
-        if (hexStart != -1) {
-            int hexEnd = in.indexOf(' ', hexStart);
-            if (hexEnd != -1) {
-                return in.substring(hexStart, hexEnd);
-            }
-        }
-
-        int octets = 0;
-        int lastIndex, old, end;
-
-        if (in.indexOf('-') > -1) {
-            in = in.replace('-', ':');
-        }
-
-        lastIndex = in.lastIndexOf(':');
-
-        if (lastIndex > in.length() - 2)
-            return null;
-
-        end = Math.min(in.length(), lastIndex + 3);
-
-        ++octets;
-        old = lastIndex;
-        while (octets != 5 && lastIndex != -1 && lastIndex > 1) {
-            lastIndex = in.lastIndexOf(':', --lastIndex);
-            if (old - lastIndex == 3 || old - lastIndex == 2) {
-                ++octets;
-                old = lastIndex;
-            }
-        }
-
-        if (octets == 5 && lastIndex > 1) {
-            return in.substring(lastIndex - 2, end).trim();
-        }
-        return null;
-    }
-
-    /**
-     * Parses a <code>long</code> from a hex encoded number. This method will 
skip
-     * all characters that are not 0-9 and a-f (the String is lower cased 
first).
-     * Returns 0 if the String does not contain any interesting characters.
-     *
-     * @param s the String to extract a <code>long</code> from, may not be 
<code>null</code>
-     * @return a <code>long</code>
-     * @throws NullPointerException if the String is <code>null</code>
-     */
-    private static long parseLong(String s) throws NullPointerException {
-        s = s.toLowerCase();
-        long out = 0;
-        byte shifts = 0;
-        char c;
-        for (int i = 0; i < s.length() && shifts < 16; i++) {
-            c = s.charAt(i);
-            if ((c > 47) && (c < 58)) {
-                out <<= 4;
-                ++shifts;
-                out |= c - 48;
-            } else if ((c > 96) && (c < 103)) {
-                ++shifts;
-                out <<= 4;
-                out |= c - 87;
-            }
-        }
-        return out;
-    }
-
-    /**
-     * Parses a <code>short</code> from a hex encoded number. This method will 
skip
-     * all characters that are not 0-9 and a-f (the String is lower cased 
first).
-     * Returns 0 if the String does not contain any interesting characters.
-     *
-     * @param s the String to extract a <code>short</code> from, may not be 
<code>null</code>
-     * @return a <code>short</code>
-     * @throws NullPointerException if the String is <code>null</code>
-     */
-    private static short parseShort(String s) throws NullPointerException {
-        s = s.toLowerCase();
-        short out = 0;
-        byte shifts = 0;
-        char c;
-        for (int i = 0; i < s.length() && shifts < 4; i++) {
-            c = s.charAt(i);
-            if ((c > 47) && (c < 58)) {
-                out <<= 4;
-                ++shifts;
-                out |= c - 48;
-            } else if ((c > 96) && (c < 103)) {
-                ++shifts;
-                out <<= 4;
-                out |= c - 87;
-            }
-        }
-        return out;
+        return macAddress;
     }
 }
diff --git a/utils/src/test/java/com/cloud/utils/net/MacAddressTest.java 
b/utils/src/test/java/com/cloud/utils/net/MacAddressTest.java
index 42b03b70daf..ff33ed03f00 100644
--- a/utils/src/test/java/com/cloud/utils/net/MacAddressTest.java
+++ b/utils/src/test/java/com/cloud/utils/net/MacAddressTest.java
@@ -41,14 +41,14 @@ public class MacAddressTest {
     public final void testMacAddressToLong() throws Exception {
         // TODO this test should fail this address is beyond the acceptable 
range for macaddresses
         MacAddress mac = new MacAddress(Long.MAX_VALUE);
-        assertEquals(Long.MAX_VALUE,mac.toLong());
+        assertEquals(Long.MAX_VALUE, mac.toLong());
         System.out.println(mac.toString());
     }
 
-    // TODO    public final void testToLong() throws Exception {
-    // TODO    public final void testToByteArray() throws Exception {
-    // TODO    public final void testToStringString() throws Exception {
-    // TODO    public final void testToString() throws Exception {
-    // TODO    public final void testGetMacAddress() throws Exception {
-    // TODO    public final void testParse() throws Exception {
+    @Test
+    public final void testSpecificMacAddress() throws Exception {
+        // Test specific mac address 76:3F:76:EB:02:81
+        MacAddress mac = new MacAddress(130014950130305L);
+        assertEquals("76:3f:76:eb:02:81", mac.toString());
+    }
 }

Reply via email to