27

I can use

ip = InetAddress.getLocalHost();
NetworkInterface.getByInetAddress(ip);

to obtain the mac address, but if I use this code in an offline machine it doesn't work.

So, How can I get the Mac address?

Matt Ball
  • 354,903
  • 100
  • 647
  • 710
Jevivre xavie
  • 303
  • 1
  • 4
  • 11
  • 3
    Technically, you should treat an offline machine as though it has no network card anyway. How do you deal with that latter case? – C. K. Young May 28 '11 at 20:28
  • 1
    Why does your program need this information? What benefit does it provide to the end user? – Andrew Thompson May 28 '11 at 20:58
  • And what if the machine has more than one? And are you aware that the MAC address can be changed by the user? There is nothing you can do with a MAC address in Java except try to use it as a machine identifier, which it is not adequate for. – user207421 May 28 '11 at 23:34
  • 2
    thanks, I try to use it as a machine identifier, so What is the proper way to identify a machine in java? – Jevivre xavie May 30 '11 at 19:51
  • You try to use it as a machine identifier even though it can't be used as a machine identifier? – user207421 Oct 31 '14 at 04:55
  • 3
    @EJP what is your proposal for this? – Brethlosze May 15 '15 at 02:29

9 Answers9

38

With Java 6+, you can use NetworkInterface.getHardwareAddress.

Bear in mind that a computer can have no network cards, especially if it's embedded or virtual. It can also have more than one. You can get a list of all network cards with NetworkInterface.getNetworkInterfaces().

phihag
  • 278,196
  • 72
  • 453
  • 469
  • 5
    I had an issue, that I on some computers only got a truncated, 4-byte mac-address. I managed to solve this by including -Djava.net.preferIPv4Stack=true as startup parameter for java – runholen Dec 08 '14 at 14:52
27

With all the possible solutions that i've found here and another replies, then i will contribute with my solution. You need to specify a parameter with a String containing "ip" or "mac" depending on what you need to check. If the computer has no interface, then it will return an String containing null, otherwise will return a String containing what you asked for (the ip address or the mac).

How to use it:

System.out.println("Ip: " + GetNetworkAddress.GetAddress("ip"));
System.out.println("Mac: " + GetNetworkAddress.GetAddress("mac"));

Result (if the computer has a network card):

Ip: 192.168.0.10 
Mac: 0D-73-ED-0A-27-44

Result (if the computer doesn't have a network card):

Ip: null
Mac: null

Here's the code:

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;

public class GetNetworkAddress {

    public static String GetAddress(String addressType) {
        String address = "";
        InetAddress lanIp = null;
        try {

            String ipAddress = null;
            Enumeration<NetworkInterface> net = null;
            net = NetworkInterface.getNetworkInterfaces();

            while (net.hasMoreElements()) {
                NetworkInterface element = net.nextElement();
                Enumeration<InetAddress> addresses = element.getInetAddresses();

                while (addresses.hasMoreElements() && element.getHardwareAddress().length > 0 && !isVMMac(element.getHardwareAddress())) {
                    InetAddress ip = addresses.nextElement();
                    if (ip instanceof Inet4Address) {

                        if (ip.isSiteLocalAddress()) {
                            ipAddress = ip.getHostAddress();
                            lanIp = InetAddress.getByName(ipAddress);
                        }

                    }

                }
            }

            if (lanIp == null)
                return null;

            if (addressType.equals("ip")) {

                address = lanIp.toString().replaceAll("^/+", "");

            } else if (addressType.equals("mac")) {

                address = getMacAddress(lanIp);

            } else {

                throw new Exception("Specify \"ip\" or \"mac\"");

            }

        } catch (UnknownHostException ex) {

            ex.printStackTrace();

        } catch (SocketException ex) {

            ex.printStackTrace();

        } catch (Exception ex) {

            ex.printStackTrace();

        }

        return address;

    }

    private static String getMacAddress(InetAddress ip) {
        String address = null;
        try {

            NetworkInterface network = NetworkInterface.getByInetAddress(ip);
            byte[] mac = network.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) ? "-" : ""));
            }
            address = sb.toString();

        } catch (SocketException ex) {

            ex.printStackTrace();

        }

        return address;
    }

    private static boolean isVMMac(byte[] mac) {
        if(null == mac) return false;
        byte invalidMacs[][] = {
                {0x00, 0x05, 0x69},             //VMWare
                {0x00, 0x1C, 0x14},             //VMWare
                {0x00, 0x0C, 0x29},             //VMWare
                {0x00, 0x50, 0x56},             //VMWare
                {0x08, 0x00, 0x27},             //Virtualbox
                {0x0A, 0x00, 0x27},             //Virtualbox
                {0x00, 0x03, (byte)0xFF},       //Virtual-PC
                {0x00, 0x15, 0x5D}              //Hyper-V
        };

        for (byte[] invalid: invalidMacs){
            if (invalid[0] == mac[0] && invalid[1] == mac[1] && invalid[2] == mac[2]) return true;
        }

        return false;
    }

}

UPDATED 02/05/2017: Thanks to @mateuscb on the post How to Determine Internet Network Interface in Java that unfortunately didn't get any upvote on that post before, but he contributed to this update.

The method has been improved to skip virtual machine network cards (most popular VM software)

Jesus Flores
  • 640
  • 8
  • 15
  • What do I do if this gives an `ArrayIndexOutOfBounds` exception at `if (invalid[0] == mac[0] && invalid[1] == mac[1] && invalid[2] == mac[2]) return true;`? – S_S Sep 27 '17 at 10:55
  • @Sumit check the number of items that are in both arrays "invalid" and "mac" because one of them or both have less than three items – Jesus Flores Sep 27 '17 at 11:11
  • So I found another piece of code at https://stackoverflow.com/a/16449379/3169868 which shows the first MAC address as blank and remaining 3 (including VMs). Can this code be modified to handle this? – S_S Sep 27 '17 at 11:17
  • @Sumit try replacing this line `while (addresses.hasMoreElements() && !isVMMac(element.getHardwareAddress())) {` by `while (addresses.hasMoreElements() && element.getHardwareAddress().length > 0 && !isVMMac(element.getHardwareAddress())) {` – Jesus Flores Sep 27 '17 at 11:46
  • 1
    Thanks, works fine now! Perhaps you may consider updating the sample code in the answer as well. – S_S Sep 29 '17 at 05:07
5

As for the computer being offline, it usually doesn't have an IP assigned, because DHCP is widely used...

And for the question in the title: NetworkInterface.getHardwareAddress()

Uku Loskit
  • 40,868
  • 9
  • 92
  • 93
1

Try this:

final NetworkInterface netInf = NetworkInterface.getNetworkInterfaces().nextElement();
final byte[] mac = netInf.getHardwareAddress();
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < mac.length; i++) {
        sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));        
}
log.info("Mac addr: {}", sb.toString());
Rudi Wijaya
  • 872
  • 1
  • 10
  • 25
1

Cleaned up code from here:

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;

public class HardwareAddress
{
    public static String getMacAddress() throws UnknownHostException,
            SocketException
    {
        InetAddress ipAddress = InetAddress.getLocalHost();
        NetworkInterface networkInterface = NetworkInterface
                .getByInetAddress(ipAddress);
        byte[] macAddressBytes = networkInterface.getHardwareAddress();
        StringBuilder macAddressBuilder = new StringBuilder();

        for (int macAddressByteIndex = 0; macAddressByteIndex < macAddressBytes.length; macAddressByteIndex++)
        {
            String macAddressHexByte = String.format("%02X",
                    macAddressBytes[macAddressByteIndex]);
            macAddressBuilder.append(macAddressHexByte);

            if (macAddressByteIndex != macAddressBytes.length - 1)
            {
                macAddressBuilder.append(":");
            }
        }

        return macAddressBuilder.toString();
    }
}
BullyWiiPlaza
  • 17,329
  • 10
  • 113
  • 185
0

Medium access control address (MAC address)

MAC address of a device is a unique identifier assigned to a network interface controller (NIC). For communications within a network segment, it is used as a network address for most IEEE 802 network technologies, including Ethernet, Wi-Fi, and Bluetooth. Within the Open Systems Interconnection (OSI) model, MAC addresses are used in the medium access control protocol sublayer of the data link layer.

MAC addresses are most often assigned by the manufacturer of network interface cards. Each is stored in hardware, such as the card's read-only memory or by a firmware mechanism.

Use the following function getPhysicalAddress() to get list of MAC address:

static String format = "%02X"; // To get 2 char output.
private static String[] getPhysicalAddress() throws Exception{
    try {
        // DHCP Enabled - InterfaceMetric
        Set<String> macs = new LinkedHashSet<String>();

        Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces();
        while( nis.hasMoreElements() ) {
            NetworkInterface ni = nis.nextElement();
            byte mac [] = ni.getHardwareAddress(); // Physical Address (MAC - Medium Access Control)
            if( mac != null ) {
                final StringBuilder macAddress = new StringBuilder();
                for (int i = 0; i < mac.length; i++) {
                    macAddress.append(String.format("%s"+format, (i == 0) ? "" : ":", mac[i]) );
                    //macAddress.append(String.format(format+"%s", mac[i], (i < mac.length - 1) ? ":" : ""));
                }
                System.out.println(macAddress.toString());
                macs.add( macAddress.toString() );
            }
        }
        return macs.toArray( new String[0] );
    } catch( Exception ex ) {
        System.err.println( "Exception:: " + ex.getMessage() );
        ex.printStackTrace();
    }
    return new String[0];
}
public static void main(String[] args) throws Exception {
    InetAddress localHost = InetAddress.getLocalHost();
    System.out.println("Host/System Name : "+ localHost.getHostName());
    System.out.println("Host IP Address  : "+ localHost.getHostAddress());

    String macs2 [] = getPhysicalAddress();
    for( String mac : macs2 )
        System.err.println( "MacAddresses = " + mac );
}

The above function works as ipconfig/all|find "Physical Address" >>MV-mac.txt.

D:\>ipconfig /all|find "Physical Address"
   Physical Address. . . . . . . . . : 94-57-A6-00-0C-BB
   Physical Address. . . . . . . . . : 01-FF-60-93-0B-88
   Physical Address. . . . . . . . . : 62-B8-9A-2B-F3-87
   Physical Address. . . . . . . . . : 60-B8-9A-2B-F3-87
   Physical Address. . . . . . . . . : 60-B8-9A-2B-F3-87

The IEEE divides the OSI data link layer into two separate sublayers:

  • Logical link control (LLC): Transitions up to the network layer
  • MAC: Transitions down to the physical layer Image ref

getmac

Returns the media access control (MAC) address and list of network protocols associated with each address for all network cards in each computer, either locally or across a network.

D:\>getmac /fo csv /nh

NET START command

D:\>netsh interface ipv4 show addresses
Yash
  • 9,250
  • 2
  • 69
  • 74
0

Another way is to use an OS command 'getmac' through native code execution.

    Process p = Runtime.getRuntime().exec("getmac /fo csv /nh");
    java.io.BufferedReader in = new java.io.BufferedReader(new  java.io.InputStreamReader(p.getInputStream()));
    String line;
    line = in.readLine();        
    String[] result = line.split(",");

    System.out.println(result[0].replace('"', ' ').trim());
Olantobi
  • 869
  • 1
  • 8
  • 16
0

Kotlin:

NetworkInterface.getNetworkInterfaces()
    .asSequence()
    .mapNotNull { ni ->
        ni.hardwareAddress?.joinToString(separator = "-") {
            "%02X".format(it)
        }
    }.toList()
Ahmed Mourad
  • 193
  • 1
  • 2
  • 18
-1
public static void main(String[] args){

        InetAddress ip;
        try {

            ip = InetAddress.getLocalHost();
            System.out.println("Current IP address : " + ip.getHostAddress());

            NetworkInterface network = NetworkInterface.getByInetAddress(ip);

            byte[] mac = network.getHardwareAddress();

            System.out.print("Current MAC address : ");

            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(sb.toString());

        } catch (Exception e) {

            e.printStackTrace();

        }

       }

output:

Current IP address : 192.168.21.60
Current MAC address : 70-5A-0F-3C-84-F2
Dmitriy
  • 5,525
  • 12
  • 25
  • 38