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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14955504/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 19:03:58  来源:igfitidea点击:

Finding original MAC address from Hardware itself

linuxsocketslinux-kernellinux-device-drivermac-address

提问by Jatin Bodarya

Os:REDHAT LINUX Linux manage: 2.6.18.8-1 #

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

Is this possible to read MAC address form NIC directly ? I have below code but it just read from above layer but not the card itself !!!

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

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 if the address has been changed, say by using 'ifconfig eth0 hw ether uu:vv:ww:yy:xx:zz',or I set "permanent" it using vi /etc/sysconfig/network-scripts/ifcfg-eth0.this file...I can successfully UPit in REBOOTalso. how do I find the original? 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 for it or command for it? I suppose to write C code for it. but don't know how to do this in above case.

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

** below code gives my currentMAC but not original MAC

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

回答by begemotv2718

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

好吧,旧的以太网地址保留在卡 eeprom 的第一个字节中(至少对于某些类型的卡),因此可以使用 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

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

回答by Mats Petersson

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 it's 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.

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

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.

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

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.

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

回答by Jason Morgan

Certainly in ethtool 3.1 you can just print the address: ethtool -P|--show-permaddr DEVNAME Show permanent hardware address

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

e.g.

例如

ethtool -P eth0

Permanent address: 94:de:80:6a:21:25

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

回答by user3462738

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.

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

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 eth0or wlan0).

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

回答by tver3305

Try cat /sys/class/net/eth0/addressor cat /sys/class/net/em1/addressif using Fedora. It should work.

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

The original answer is here: Notes of a Systems Admin

原始答案在这里:系统管理员的笔记

回答by R4C3R

This command lists all the ethernet devices and original HW addresses.

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

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

回答by Mian Asbat Ahmad

In Ubuntu 18.4 LTS
First you need to find the network interface names on the computer by command

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

ls /sys/class/net

My output is

我的输出是

docker0  enp0s31f6  lo

Now you can use the command as discussed above, dont forget the sudo

现在您可以使用上面讨论的命令,不要忘记 sudo

sudo ethtool -P enp0s31f6