B4J Code Snippet Get all MAC Addresses on Windows/Linux

I need for an app to set a unique database index and computer hardware based. I've searched for this info in the Forum and I found the jGetMAC library from @giga and this post from @Erel

The jGetMAC library only returns one MAC Address (and I've 5 MAC Addresses/interfaces on my windows system) and the returned MAC doesn't correspond to the Eth interface/nor Wifi interface.

So I've adapted the @Erel code to display only the interfaces which have MAC Addresses (independently if the interfaces are up/down or have IP address assigned to it).

Java class info on http://docs.oracle.com/javase/8/docs/api/java/net/NetworkInterface.html

B4X:
Sub AppStart (Form1 As Form, Args() As String)

    Dim jo As JavaObject = Me
    jo.RunMethod("PrintAllInterfaces", Null)

End Sub


Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
    Return True
End Sub
#if JAVA


import java.net.NetworkInterface;
import java.util.Enumeration;

public static void PrintAllInterfaces() throws Exception {
      for (Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces(); e.hasMoreElements();)
     {
          NetworkInterface network = e.nextElement();
        byte[] mac = network.getHardwareAddress();
      
                if (mac != null)  {
                  
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < mac.length; i++) {
                          sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));       
                      }
                    //Interface properties
                    System.out.println("Current MAC address : " + sb.toString() +"\r\n");
                    System.out.println(network.getDisplayName());
                    System.out.println(network.getName());                      
                  
                }    
      }
}
#End If

Log results:

Current MAC address : 20-6A-8A-A4-B7-89
Realtek PCIe GBE Family Controller #2
eth1
Current MAC address : 5C-93-A2-C8-5E-CB
Qualcomm Atheros AR956x Wireless Network Adapter
wlan0
Current MAC address : 1E-93-A2-C8-5E-CB
Adaptador virtual directo Wi-Fi de Microsoft
wlan1
Current MAC address : 5E-93-A2-C8-5E-CB
Adaptador virtual de red hospedada de Microsoft
wlan2
Current MAC address : 00-00-00-00-00-00-00-E0
Adaptador ISATAP de Microsoft
net1
Current MAC address : 00-00-00-00-00-00-00-E0
Adaptador ISATAP de Microsoft #3
net3
Current MAC address : 0A-00-27-00-00-00
VirtualBox Host-Only Ethernet Adapter #2
eth4
Current MAC address : 00-00-00-00-00-00-00-E0
Adaptador ISATAP de Microsoft #4
net5
Current MAC address : 02-00-4C-4F-4F-50
Npcap Loopback Adapter
eth5
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
Did a few changes on this to return a b4j list with the details...

Create a B4J Class

B4X:
Sub Class_Globals
    Private NativeMe As JavaObject
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize
    NativeMe = Me
End Sub

Sub GetMacAddresses() As List
    Return NativeMe.RunMethodJO("GetMacs", Null)
End Sub

#if JAVA
import java.net.NetworkInterface;
import java.util.Enumeration;
import anywheresoftware.b4a.objects.collections.Map;
import anywheresoftware.b4a.objects.collections.List;

public Object GetMacs() throws Exception {
    List macs = new anywheresoftware.b4a.objects.collections.List();
    macs.Initialize();
    
      for (Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces(); e.hasMoreElements();)
     {
          NetworkInterface network = e.nextElement();
        byte[] mac = network.getHardwareAddress();
      
                if (mac != null)  {
                  
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < mac.length; i++) {
                          sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));       
                      }
                    //Interface properties
                    Map eachMac = new anywheresoftware.b4a.objects.collections.Map();
                    eachMac.Initialize();
                    eachMac.Put("displayname",network.getDisplayName());
                    eachMac.Put("name",network.getName());
                    eachMac.Put("mac",sb.toString());
                    macs.Add(eachMac.getObject());
                }   
      }
      return macs.getObject();
}
#End If

Then in b4j, call

B4X:
Dim mm As MashMacAddress
    mm.Initialize
    
    Dim macs As List = mm.GetMacAddresses
    For Each macm As Map In macs
        Log(macm)
    Next
B4X:
Dim mm As MashMacAddress
    mm.Initialize
    
    Dim macs As List = mm.GetMacAddresses
    For Each macm As Map In macs
        Log(macm)
    Next

Note tested on Linux, seems to be working well in windows..
 

Jaume Guillem

Member
Licensed User
Longtime User
It works perfect. Thank you.
Do you know any way to filter the ones that correspond to physical devices?
isvirtual () does not report it well

In this example only the first two are of interest, but I do not know how to filter them
B4X:
(MyMap) {displayname = Broadcom 802.11ac Network Adapter, isup = true, isvirtual = false, name = wlan0, mac = B3-07-8A-BB-12-75}
(MyMap) {displayname = Broadcom NetXtreme Gigabit Ethernet, isup = true, isvirtual = false, name = eth4, mac = AD-85-A6-11-44-D5}
(MyMap) {displayname = VMware Virtual Ethernet Adapter for VMnet1, isup = true, isvirtual = false, name = eth5, mac = 00-50-56-C0-00-01}
(MyMap) {displayname = VMware Virtual Ethernet Adapter for VMnet8, isup = true, isvirtual = false, name = eth6, mac = 00-50-56-C0-00-08}
 

inakigarm

Well-Known Member
Licensed User
Longtime User
It works perfect. Thank you.
Do you know any way to filter the ones that correspond to physical devices?
isvirtual () does not report it well
[/code]
Look at https://stackoverflow.com/questions/42504037/get-physical-mac-address-in-java to adapt the above code; in short, the code check if the Mac address obtained belongs to an array of "virtual machine names" as "VirtualBox", "Hyper-V",VMware", etc and in that case, not adding to the MAC address list (theoretically, the hardware Mac Address list)

B4X:
        private static final String[] VIRTUAL_ADAPTER_NAMES = { "VirtualBox", "Hyper-V" };
        . . . . . . . .

        String name = networkInterface.getDisplayName();
        for (String vName : VIRTUAL_ADAPTER_NAMES) {
            if (name.contains(vName)) {
                return false;
            }
 

MarcTG

Active Member
Licensed User
Longtime User
Hi inakigarm,
Can you please share a full working code of this?
I am trying to create something that searches a PC for its MAC addresses and compares it to a list that I create...

Thanks!
 

inakigarm

Well-Known Member
Licensed User
Longtime User
Hi inakigarm,
Can you please share a full working code of this?
I am trying to create something that searches a PC for its MAC addresses and compares it to a list that I create...

Thanks!
Have you tried code in Post#1 or #3? It seems it's what you're looking for.
 

MarcTG

Active Member
Licensed User
Longtime User
Yes I have, #1 did work but #3 is closer to what I am looking for and it didn't work...
 

inakigarm

Well-Known Member
Licensed User
Longtime User
Works fine here (test program atttached)
 

Attachments

  • GetmacTest.zip
    1.7 KB · Views: 450

aminoacid

Active Member
Licensed User
Longtime User
GetMACAddress() will not return the MAC address if an IP address has not be assigned to the interface. Is there any way to change that? i.e. obtain the MAC addresses of all interfaces, regardless of whether an IP address has been assigned or not.
Thanks!
 
Top