'Finding original MAC address from hardware itself
Is it possible to read the MAC address from the NIC directly? I have the code below but it just reads from the layer above but not the card itself.
I'm trying to figure out how to find the original MAC address of an Ethernet NIC on my Linux box. I understand how to find the current MAC address using ifconfig.
But the address can be changed, say by using
ifconfig eth0 hw ether uu:vv:ww:yy:xx:zz
or setting it "permanently" using /etc/sysconfig/network-scripts/ifcfg-eth0.
How do I find the original MAC address? There must be a way to find it, because it is still burned permanently into the card, but I can't find a tool to read the burned in address.
Is there any utility or command for that?
I suppose it should be possible to write C code for it, below code gives my current MAC but not the original MAC:
#include <stdio.h> /* Standard I/O */
#include <stdlib.h> /* Standard Library */
#include <errno.h> /* Error number and related */
#define ENUMS
#include <sys/socket.h>
#include <net/route.h>
#include <net/if.h>
#include <features.h> /* for the glibc version number */
#if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1
#include <netpacket/packet.h>
#include <net/ethernet.h> /* the L2 protocols */
#else
#include <asm/types.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h> /* The L2 protocols */
#endif
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/un.h>
#include <sys/ioctl.h>
#include <netdb.h>
int main( int argc, char * argv[] ){
unsigned char mac[IFHWADDRLEN];
int i;
get_local_hwaddr( argv[1], mac );
for( i = 0; i < IFHWADDRLEN; i++ ){
printf( "%02X:", (unsigned int)(mac[i]) );
}
}
int get_local_hwaddr(const char *ifname, unsigned char *mac)
{
struct ifreq ifr;
int fd;
int rv; // return value - error value from df or ioctl call
/* determine the local MAC address */
strcpy(ifr.ifr_name, ifname);
fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
if (fd < 0)
rv = fd;
else {
rv = ioctl(fd, SIOCGIFHWADDR, &ifr);
if (rv >= 0) /* worked okay */
memcpy(mac, ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
}
return rv;
}
OS: Red Hat Linux, 2.6.18.8-1
Solution 1:[1]
Certainly in ethtool you can just print the address:
-P --show-permaddr Queries the specified network device for permanent hardware address.
e.g.
ethtool -P eth0
produces
Permanent address: 94:de:80:6a:21:25
Solution 2:[2]
Try cat /sys/class/net/eth0/address or cat /sys/class/net/em1/address if using Fedora. It should work.
The original answer is here: Notes of a Systems Admin
Solution 3:[3]
The only way to find the original MAC address is to use the same method the network card driver does - unfortunately, I don't believe there is a generic way to tell the driver to provide its MAC address "as provided by the hardware". Of course, there are cases where there isn't a hardware network card for that particular interface - virtual network drivers for virtualization and when using bridges and software switches for example.
And of course, the hardware may be such that you can't actually read the "original" MAC address when it has been overwritten by software, because there is only one set of registers for the MAC address itself.
I had a quick look at the pcnet32.c drivers (because it's one of the models of network card that I have a rough idea how it works and where the different registers are, etc, so I can see what it does). As far as I can see, it supports no method of actually asking "what is your PROM Ethernet address" - the MAC address is read out during the "probe1" section of the module initialization, and stored away. No further access to those hardware registers is made.
Solution 4:[4]
Well, the old ethernet address remains in the first bytes of the card eeprom (at least for some types of cards), so it is possible to extract it using ethtool
bash$ sudo ethtool -e eth1
Offset Values
------ ------
0x0000 tt uu ww xx yy zz 79 03
0x....
where tt:uu:ww:xx:yy:zz is old mac address
Solution 5:[5]
This may not be the programmatic way, but why not search dmesg. All of my machines' NICs spit out the MAC address at detection time.
Try something like this:
dmesg|grep eth0
Different NICs display the MAC address differently, but the log will always contain the kernel given name of the adapter (in most cases eth0 or wlan0).
Solution 6:[6]
In Ubuntu 18.4 LTS
First you need to find the network interface names on the computer by command
ls /sys/class/net
My output is
docker0 enp0s31f6 lo
Now you can use the command as discussed above, dont forget the sudo
sudo ethtool -P enp0s31f6
Solution 7:[7]
This command lists all the ethernet devices and original HW addresses.
dmesg | grep eth | grep IRQ | awk {'print "permanent address of " $5 " " $9'} |tr "," " "
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Matthias Braun |
| Solution 2 | tver3305 |
| Solution 3 | Matthias Braun |
| Solution 4 | begemotv2718 |
| Solution 5 | Youssef Bouhjira |
| Solution 6 | Mian Asbat Ahmad |
| Solution 7 |
