title: Finding original MAC address from hardware itself
body: <p><strong>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.</strong></p>
  <p>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.</p>
  <p>But the address can be changed, say by using</p>
  <pre><code>ifconfig eth0 hw ether uu:vv:ww:yy:xx:zz
  </code></pre>
  <p>or setting it &quot;permanently&quot; using <code>/etc/sysconfig/network-scripts/ifcfg-eth0</code>.</p>
  <p>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.</p>
  <p>Is there any utility or command for that?</p>
  <p>I suppose it should be possible to write C code for it, below code gives my <em>current</em> MAC but not the original MAC:</p>
  <pre><code>#include &lt;stdio.h&gt;              /* Standard I/O */
  #include &lt;stdlib.h&gt;             /* Standard Library */
  #include &lt;errno.h&gt;              /* Error number and related */
  
  
  #define ENUMS
  #include &lt;sys/socket.h&gt;
  #include &lt;net/route.h&gt;
  #include &lt;net/if.h&gt;
  #include &lt;features.h&gt;           /* for the glibc version number */
  #if __GLIBC__ &gt;= 2 &amp;&amp; __GLIBC_MINOR &gt;= 1
  #include &lt;netpacket/packet.h&gt;
  #include &lt;net/ethernet.h&gt;       /* the L2 protocols */
  #else
  #include &lt;asm/types.h&gt;
  #include &lt;linux/if_packet.h&gt;
  #include &lt;linux/if_ether.h&gt;     /* The L2 protocols */
  #endif
  #include &lt;netinet/in.h&gt;
  #include &lt;arpa/inet.h&gt;
  #include &lt;sys/un.h&gt;
  #include &lt;sys/ioctl.h&gt;
  #include &lt;netdb.h&gt;
  
  
  int main( int argc, char * argv[] ){
  
  unsigned char  mac[IFHWADDRLEN];
  int i;
      get_local_hwaddr( argv[1], mac );
      for( i = 0; i &lt; IFHWADDRLEN; i++ ){
          printf( &quot;%02X:&quot;, (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 &lt; 0)
          rv = fd;
      else {
          rv = ioctl(fd, SIOCGIFHWADDR, &amp;ifr);
          if (rv &gt;= 0)            /* worked okay */
              memcpy(mac, ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
      }
      return rv;
  }
  </code></pre>
  <p>OS: Red Hat Linux, 2.6.18.8-1</p>