从硬件本身查找原始MAC地址

操作系统:REDHAT LINUX Linuxpipe理:2.6.18.8-1#

这是否可以直接读取MAC地址forms的网卡? 我有下面的代码,但它只是从上面的层读取,但不是卡本身!

我试图找出如何find我的Linux机箱上的以太网网卡的原始MAC地址。 我知道如何使用ifconfigfind当前的MAC地址,但是如果地址已经被改变了,比如使用'ifconfig eth0 hw ether uu:vv:ww:yy:xx:zz' ,或者我使用vi /etc/sysconfig/network-scripts/ifcfg-eth0这个文件…我也可以在REBOOT成功地将它REBOOT 。 我怎么find原来的? 必须有一种方法来find它,因为它仍然永久烧到卡上,但我找不到一个工具来阅读烧毁的地址。 有没有它的实用工具或命令? 我想为它编写C代码。 但在上述情况下不知道如何做到这一点。

**下面的代码给出了我目前的 MAC,但不是原来的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; } 

当然,在ethtool 3.1中,你可以打印地址:ethtool -P | –show-permaddr DEVNAME显示永久硬件地址

例如

 ethtool -P eth0 

永久地址:94:de:80:6a:21:25

如果使用Fedora,请尝试使用cat /sys/class/net/eth0/addresscat /sys/class/net/em1/address 。 它应该工作。

原来的答案在这里: 系统管理员的注意事项

找到原始MAC地址的唯一方法是使用网卡驱动程序的相同方法 – 不幸的是,我不相信有一种通用的方式来告诉驱动程序提供它的MAC地址“由硬件提供”。 当然,有些情况下,特定接口没有硬件网卡 – 虚拟化的虚拟网络驱动程序,以及使用网桥和软件交换机的情况。

当然,当硬件被软件覆盖时,硬件可能实际上不能读取“原始”MAC地址,因为MAC地址本身只有一组寄存器。

我快速浏览了pcnet32.c驱动程序(因为它是网卡的一个模型,我有一个粗略的想法,它是如何工作的,以及不同的寄存器等等,所以我可以看到它的作用)。 就我所知,它不支持实际询问“PROM以太网地址是什么”的方法 – 在模块初始化的“probe1”部分读取MAC地址并将其保存起来。 没有进一步访问这些硬件寄存器。

那么,旧的以太网地址仍然在卡eeprom的第一个字节(至少对某些类型的卡),所以可以使用ethtool

 bash$ sudo ethtool -e eth1 Offset Values ------ ------ 0x0000 tt uu ww xx yy zz 79 03 0x.... 

其中tt:uu:ww:xx:yy:zz是旧的mac地址

这可能不是编程方式,但为什么不搜索dmesg 。 我的所有机器的网卡在检测时都吐出MAC地址。

尝试这样的事情:

 dmesg|grep eth0 

不同的网卡显示不同的MAC地址,但日志将始终包含内核给定的适配器名称(在大多数情况下, eth0wlan0 )。

该命令列出所有以太网设备和原始硬件地址。

 dmesg | grep eth | grep IRQ | awk {'print "permanent address of " $5 " " $9'} |tr "," " "