I wrote some C code having a rudimentary software licensing function within, where the executable will only run if the MAC address of the system I whitelisted in my C code. I only want this to work in linux.

I was accessing /sys/class/net/eth0/address which contains something like a0:b1:c2:d3:e4:f5 all in lower case on one line, making it very easy to get the MAC address. This works only if you have eth0 because I hard coded fopen( "/sys/class/net/eth0/address", "r" );

The problem I am realizing is the eth0 part. With BiosDevName and/or Predictable Network Interface Naming being the default now [in RHEL/CentOS 7] I am seeing something like eno1 rather than eth0 as the first network device having a MAC address. And this can vary greatly from system to system. So I am dealing with /sys/class/net/<unknown>/address.

What is the most portable and reliable, and not to hard, of a way to get the MAC address(es) of a linux system? Oftentimes the servers I deal with have quad port Intel NIC's, but I really only need the first one. And my code doesn't care what the network interface names are, I just need to know one or more MAC addresses that are present.

  • Did you figure this out?
    – cutrightjm
    Jan 26, 2020 at 5:03
  • yeah, I use popen in C to parse output of ifconfig and wrote a significant chunk of C to do so, since the output of ifconfig varies between linux distro's. Using /sys/class/net/<unknown>/address is not readable by anyone other than root which posed a problem.
    – ron
    Jan 27, 2020 at 14:25
  • You should post that as an answer then to help future people. However, those files can be read by non-root users at least on CentOS 7 and Debian; the permissions are set to 444.
    – cutrightjm
    Jan 29, 2020 at 2:30

1 Answer 1


If you just need to pull MAC addresses for a system and pair to an interface, we can do this Bash and feed it to the C program. If we look in /sys/class/net/*/, we can see that an interface's name is contained in the uevent file, while the MAC address is in the address file; so, we can combine those two files together per interface. Note: My bash isn't the prettiest, there is probably a better way to do this.

[user@headdesk eth0]$ cat /sys/class/net/*/uevent /sys/class/net/*/address | grep -v IFINDEX | column | sed 's/INTERFACE=//'
eth0            fa:16:3e:ac:48:74
lo              00:00:00:00:00:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .