33

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

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

我试图弄清楚如何在我的 linux 机器上找到以太网 NIC 的原始 MAC 地址。我了解如何使用 ifconfig 找到当前的 MAC 地址,但是如果地址已更改,例如 使用 .this 文件'ifconfig eth0 hw ether uu:vv:ww:yy:xx:zz',或者我使用 .this 文件设置“永久”它......vi /etc/sysconfig/network-scripts/ifcfg-eth0我也可以成功。如何找到原件?一定有办法找到它,因为它仍然被永久烧录到卡中,但我找不到读取烧录地址的工具。是否有任何实用程序或命令?我想为它编写C代码。但不知道在上述情况下如何做到这一点。UPREBOOT

** 下面的代码给出了我当前的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;
}
4

7 回答 7

60

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

例如

ethtool -P eth0

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

于 2013-12-19T16:26:19.717 回答
18

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

于 2014-06-02T15:05:40.087 回答
8

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

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

我快速浏览了 pcnet32.c 驱动程序(因为它是网卡的模型之一,我大致了解它的工作原理以及不同的寄存器在哪里等,所以我可以看到它的作用)。据我所知,它不支持实际询问“你的 PROM 以太网地址是什么”的方法——MAC 地址在模块初始化的“probe1”部分被读出并存储起来。不再对这些硬件寄存器进行访问。

于 2013-02-19T11:21:46.643 回答
7

好吧,旧的以太网地址保留在卡 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 地址

于 2013-02-19T11:20:52.120 回答
6

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

尝试这样的事情:

dmesg|grep eth0

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

于 2014-03-26T05:45:30.217 回答
0

在 Ubuntu 18.4 LTS
中首先需要通过命令找到电脑上的网络接口名称

ls /sys/class/net

我的输出是

docker0  enp0s31f6  lo

现在你可以使用上面讨论的命令了,别忘了 sudo

sudo ethtool -P enp0s31f6
于 2019-11-13T22:27:31.777 回答
-1

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

dmesg | grep eth | grep IRQ | awk {'print "permanent address of " $5 " " $9'} |tr "," " "
于 2016-03-04T12:11:39.967 回答