NodeJS - get MAC address when offline

6.6k views Asked by At

Similar to this question in C#, is it possible in NodeJS to get the MAC address(es) of a computer when disconnected from a network?

I have been using the macaddress module, which works great when the user is connected to a network -- but if the user disconnects, macaddress will not return any addresses on some systems.

I noticed some differences between os.networkInterfaces() when a user is offline/online, as well as differences in behavior across Windows/Mac and Node v10/v12. I'm not really sure where the problem actually lies here.

4

There are 4 answers

4
Gepser Hoil On

I just tested with getmac module and works fine offline (and online).

You can try it like this:

require('getmac').getMac(function(err,macAddress){
    if (err)  throw err
    console.log(macAddress) // 77:31:c2:c5:03:10
})

If you don't want to use a module you can also ask for each mac address interface like this (node >= 0.11):

require('os').networkInterfaces()

And then parse it depending of your needs.

The result should look like this:

{ lo0:
   [ { address: '::1',
       netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
       family: 'IPv6',
       mac: '00:00:00:00:00:00',
       scopeid: 0,
       internal: true },
     { address: '127.0.0.1',
       netmask: '255.0.0.0',
       family: 'IPv4',
       mac: '00:00:00:00:00:00',
       internal: true },
     { address: 'fe80::1',
       netmask: 'ffff:ffff:ffff:ffff::',
       family: 'IPv6',
       mac: '00:00:00:00:00:00',
       scopeid: 1,
       internal: true } ],
  en0:
   [ { address: '10.3.162.15',
       netmask: '255.255.254.0',
       family: 'IPv4',
       mac: '77:31:c2:c5:03:10',
       internal: false } ],
  vboxnet0:
   [ { address: '192.168.33.1',
       netmask: '255.255.255.0',
       family: 'IPv4',
       mac: '0a:00:27:00:00:00',
       internal: false } ],
  en3:
   [ { address: '10.3.32.45',
       netmask: '255.255.248.0',
       family: 'IPv4',
       mac: '0c:4d:e7:3d:3d:17',
       internal: false } ] }
0
Mohammad Nabi On

I recommend you to use the popular systeminformation library. It has over a million weekly downloads and it works well when you're offline or online. Plus, you can gain access to extra properties of the system as well:

Here's an example of getting the MAC:

const si = require('systeminformation');

si.networkInterfaces().then((data) => {
   console.log(data);
});

// Output ----------------------
[
  {
     iface: 'Wi-Fi',
     ifaceName: 'Intel(R) Dual Band Wireless-AC 7265',
     default: true,
     ip4: '192.168.13.112',
     ip4subnet: '255.255.255.0',
     ip6: '',
     ip6subnet: '',
     mac: 'gc:13:40:03:bx:as',
     internal: false,
     virtual: false,
     operstate: 'up',
     type: 'wireless',
     duplex: '',
     mtu: '',
     speed: 144.4,
     dhcp: true,
     dnsSuffix: '',
     ieee8021xAuth: 'Not defined',
     ieee8021xState: 'Disabled',
     carrierChanges: 0
  },
  {
     iface: 'Ethernet',
     ifaceName: 'Intel(R) Ethernet Connection (3) I218-LM',
     default: false,
     ip4: '',
     ip4subnet: '',
     ip6: '',
     ip6subnet: '',
     mac: '51:7g:9x:41:c6:aa',
     internal: undefined,
     virtual: false,
     operstate: 'down',
     type: 'wired',
     duplex: '',
     mtu: '',
     speed: 9223372036854.775,
     dhcp: true,
     dnsSuffix: '',
     ieee8021xAuth: 'Not defined',
     ieee8021xState: 'Disabled',
     carrierChanges: 0
  },
  {
     iface: 'Bluetooth Network Connection',
     ifaceName: 'Bluetooth Device (Personal Area Network)',
     default: false,
     ip4: '',
     ip4subnet: '',
     ip6: '',
     ip6subnet: '',
     mac: 'zc:13:30:28:ff:sf',
     internal: undefined,
     virtual: false,
     operstate: 'down',
     type: 'wired',
     duplex: '',
     mtu: '',
     speed: 3,
     dhcp: true,
     dnsSuffix: '',
     ieee8021xAuth: 'Not defined',
     ieee8021xState: 'Disabled',
     carrierChanges: 0
  }
];
2
Искрен Станиславов On

Currently facing the same situation. I ended up with the following code based on knowing the IP address of the interface we already know.

    var os = require('os');
    var getNetworkDataForThisIP = function(ipOfTheInterfaceWanted) {
        var networkInterfaces = os.networkInterfaces();
        var selectedInterfaceData;
        Object.keys(networkInterfaces).forEach((NetworkID, index, obj) => {
            networkInterfaces[NetworkID].forEach((data) => {
                if (data.family == "IPv4" && ipOfTheInterfaceWanted== data.address) {
                    //I created new Object because the NetworkID is not provided in the 'data' object
                    selectedInterfaceData = {
                        network: NetworkID,
                        address: data.address,
                        netmask: data.netmask,
                        family: data.family,
                        mac: data.mac,
                    };
                }
            });
        });
        return selectedInterfaceData;
    }

    var data = getNetworkDataForThisIP("192.168.5.1")
    console.log(data.network);
    console.log(data.address);
    console.log(data.netmask);
    console.log(data.family);
    console.log(data.mac);

You can modify to match your need based on something you already know.

not actually answered the question with being offline, but you can check state of !!data.

0
Charles On

I created a package to simplify getting the local machine's MAC address: https://www.npmjs.com/package/macaddress-local-machine

yarn add -D macaddress-local-machine
import macAddr from "macaddress-local-machine";
// Get the first MAC address
const macAddress = macAddr.first();
console.log(macAddress);
// Get all MAC addresses
const macAddresses = macAddr.all();
console.log(macAddresses);

returns one of the following or an array of the following respectively

interface MACAddress {
  iface: string,
  macAddr: string
}

// Example object:
{
  "iface": "eno2",
  "macAddr": "01:23:45:67:89:ab"
}