iis服务器助手广告广告
返回顶部
首页 > 资讯 > 操作系统 >【嵌入式linux】修改网口MAC地址
  • 665
分享到

【嵌入式linux】修改网口MAC地址

linux嵌入式c语言 2023-09-01 15:09:20 665人浏览 安东尼
摘要

使用带有网络功能的设备时,如果局域网内可能会连接很多台设备,为了保证网络通信正常,要确保每台设备的硬件Mac地址都不相同,一般在批量生产的时候可以根据产品序列号(sn号)固化每台设备的MAC地址,防止

使用带有网络功能的设备时,如果局域网内可能会连接很多台设备,为了保证网络通信正常,要确保每台设备的硬件Mac地址都不相同,一般在批量生产的时候可以根据产品序列号(sn号)固化每台设备的MAC地址,防止出现MAC冲突的问题。

修改MAC地址方法:
一、应用层
1.通过命令ifconfig修改:
ifconfig xxx(网口名) down
ifconfig xxx(网口名) hw ether xx:xx:xx:xx:xx:xx(MAC地址)
ifconfig xxx up(重启网卡)

如下图
在这里插入图片描述

2.通过linux的socket接口修改(上面命令行本质上也是这样实现的)
如下部分实现代码

#include #include #include #include #include #include #include #include #include int fd = -1;struct ifreq ifr;fd = Socket(AF_INET, SOCK_DGRAM, 0);if(fd < 0){printf("socket error\n");}memset(&ifr,0,sizeof(ifr));strcpy(ifr.ifr_name,eth_name);setsockopt(fd,SOL_SOCKET,SO_BINDTODEVICE,(char*)&ifr,sizeof(ifr));if(ioctl(fd,SioCGIFHWADDR,&ifr) < 0)  //获得MAC地址{printf("ioctl SIOCSIFHWADDR error\n");}unsigned char mac[6]={12,23,34,45,56,67};memcpy(ifr.ifr_hwaddr,mac,6);if(ioctl(fd,SIOCSIFHWADDR,&ifr) < 0)  //设置MAC地址{printf("ioctl SIOCSIFHWADDR error\n");}

在应用层修改MAC比较灵活方便,由app可随时设置和管理MAC地址。

二、kernel层修改
修改网卡的设备驱动,原理和下面uboot修改相似。在此不叙述。

三、uboot修改
kernel的网卡设备驱动最终是根据读网卡的MAC地址寄存器来向上层传递MAC地址的,因此在uboot修改相关寄存器也可以实现修改MAC地址。

这里以2019.01的uboot为例子。首先在uboot源码找到网络设备驱动的核心层,看看是怎么配置和初始化网络设备的。
uboot/ /net/eth-uclass.c (新的驱动基本使用DM框架,驱动核心层一般在xxx-uclass.c,老的在xxx_legacy.c一般不使用)。在网口eth_post_probe入口函数找到关于MAC地址的配置接口。

if (eth_get_ops(dev)->read_rom_hwaddr)eth_get_ops(dev)->read_rom_hwaddr(dev);eth_env_get_enetaddr_by_index("eth", dev->seq, env_enetaddr);if (!is_zero_ethaddr(env_enetaddr)) {if (!is_zero_ethaddr(pdata->enetaddr) &&memcmp(pdata->enetaddr, env_enetaddr, ARP_HLEN)) {printf("\nWarning: %s MAC addresses don't match:\n",dev->name);printf("Address in ROM is %pM\n",pdata->enetaddr);printf("Address in environment is %pM\n",env_enetaddr);}memcpy(pdata->enetaddr, env_enetaddr, ARP_HLEN);} else if (is_valid_ethaddr(pdata->enetaddr)) {eth_env_set_enetaddr_by_index("eth", dev->seq, pdata->enetaddr);printf("\nWarning: %s using MAC address from ROM\n",dev->name);} else if (is_zero_ethaddr(pdata->enetaddr) ||!is_valid_ethaddr(pdata->enetaddr)) {#ifdef CONFIG_NET_RANDOM_ETHADDRnet_random_ethaddr(pdata->enetaddr);printf("\nWarning: %s (eth%d) using random MAC address - %pM\n",dev->name, dev->seq, pdata->enetaddr);#elseprintf("\nError: %s address not set.\n",dev->name);return -EINVAL;#endif}

可得出在uboot设置MAC地址大概流程:通过在外部存储介质(ROM)、环境变量env读取或随机生成MAC地址保存到匹配到的网卡外设的驱动数据dev->platdata->enetaddr(6个字节,16进制数格式存放)里,在后续uboot初始化硬件外设的时候调用向MAC控制器的相关寄存器写MAC地址的接口,实现将enetaddr写入硬件。这里有三种方法获得MAC地址:
1.若设备驱动有实现read_rom_hwaddr接口则执行,实现从ROM中读取MAC地址保存到设备的驱动数据eth_pdata结构体中。这里以zynq-7010平台、ROM为qspi flash W25q512为例,网口的设备驱动在uboot/drivers/net/zynq_gem.c里面实现。

static const struct eth_ops zynq_gem_ops = {.start = zynq_gem_init,.send = zynq_gem_send,.recv = zynq_gem_recv,.free_pkt = zynq_gem_free_pkt,.stop = zynq_gem_halt,.write_hwaddr = zynq_gem_setup_mac,.read_rom_hwaddr = zynq_gem_read_rom_mac,};__weak int zynq_board_read_rom_ethaddr(unsigned char *ethaddr){return -ENOSYS;}static int zynq_gem_read_rom_mac(struct udevice *dev){struct eth_pdata *pdata = dev_get_platdata(dev);if (!pdata)return -ENOSYS;return zynq_board_read_rom_ethaddr(pdata->enetaddr);}

*若有定义和实现int zynq_board_read_rom_ethaddr(unsigned char ethaddr
)则会调用该接口实现从rom读取MAC地址,否则执行上述末默认弱连接的接口。这里在
uboot/board/xilinx/zynq/board.c自定义该接口的实现。

int zynq_board_read_rom_ethaddr(unsigned char *ethaddr){int ret = 0;#if 1ethaddr[0]==0x00;ethaddr[1]==0xa8;ethaddr[2]==0x22;ethaddr[3]==0x12;ethaddr[4]==0x34;ethaddr[5]==0x56#endif#if 0 unsigned int mac_offset=0x210000;//在flash的0x210000存取MAC地址unsigned int len=6;ret = board_spi_flash_probe();  //匹配spi flashif (ret){printf("spi_flash_probe fail \n");return -1;}ret = spi_flash_read(board_spi_flash, mac_offset, len, ethaddr); //从spi flashif (ret){return -2;}#endifreturn ret;}

2.MAC地址从环境变量env中获得。在上面的eth_env_get_enetaddr_by_index(“eth”, dev->seq, env_enetaddr)接口实现获得MAC地址,这种方法需要在env中定义ethaddr=xx:xx:xx:xx:xx:xx。

int eth_env_get_enetaddr_by_index(const char *base_name, int index,uchar *enetaddr){char enetvar[32];sprintf(enetvar, index ? "%s%daddr" : "%saddr", base_name, index);return eth_env_get_enetaddr(enetvar, enetaddr);}

3.当上述都不能获得有效的MAC地址,可以使用net_random_ethaddr(pdata->enetaddr);根据定时器产生的随机数生成有效、随机的MAC地址。

static inline void net_random_ethaddr(uchar *addr){int i;unsigned int seed = get_timer(0);for (i = 0; i < 6; i++)addr[i] = rand_r(&seed);addr[0] &= 0xfe; addr[0] |= 0x02; }

正确获取到MAC地址后写入MAC控制器相关寄存器调用流程:
uboot/common/board_r.c的initr_net()->eth-uclass.c的eth_initialize()->eth-uclass.c的eth_write_hwaddr(dev);->设备驱动zynq_gem.c的zynq_gem_ops.write_hwaddr →最后通过zynq_gem_setup_mac实现写入MAC控制器的MAC地址寄存器的操作。

static int zynq_gem_setup_mac(struct udevice *dev){u32 i, macaddrlow, macaddrhigh;struct eth_pdata *pdata = dev_get_platdata(dev);struct zynq_gem_priv *priv = dev_get_priv(dev);struct zynq_gem_regs *regs = priv->iobase;macaddrlow = pdata->enetaddr[0];macaddrlow |= pdata->enetaddr[1] << 8;macaddrlow |= pdata->enetaddr[2] << 16;macaddrlow |= pdata->enetaddr[3] << 24;macaddrhigh = pdata->enetaddr[4];macaddrhigh |= pdata->enetaddr[5] << 8;for (i = 0; i < 4; i++) {writel(0, &regs->laddr[i][LADDR_LOW]);writel(0, &regs->laddr[i][LADDR_HIGH]);writel(0, &regs->match[i]);}writel(macaddrlow, &regs->laddr[0][LADDR_LOW]);writel(macaddrhigh, &regs->laddr[0][LADDR_HIGH]);return 0;}寄存器结构体struct zynq_gem_regs {u32 nwctrl; u32 nwcfg; u32 nwsr; u32 reserved1;u32 dmacr; u32 txsr; u32 rxqbase; u32 txqbase; u32 rxsr; u32 reserved2[2];u32 idr; u32 reserved3;u32 phymntnc; u32 reserved4[18];u32 hashl; u32 hashh; #define LADDR_LOW 0#define LADDR_HIGH 1u32 laddr[4][LADDR_HIGH + 1]; u32 match[4]; u32 reserved6[18];#define STAT_SIZE 44u32 stat[STAT_SIZE]; u32 reserved9[20];u32 pcscntrl;u32 rserved12[36];u32 dcfg6; u32 reserved7[106];u32 transmit_q1_ptr; u32 reserved8[15];u32 receive_q1_ptr; u32 reserved10[17];u32 upper_txqbase; u32 reserved11[2];u32 upper_rxqbase; };

下图为MAC控制器的寄存器表
在这里插入图片描述

这里分别测试了从ROM读取和在env定义MAC地址的两种情况
1.在flash读取MAC地址(上述方法1)。重新编译、烧录UBOOT。系统启动后网卡配置如下,MAC已成功修改为00:A8:22:12:34:56如下图
在这里插入图片描述
2.在env镜像添加MAC地址00:0A:22:11:22:33。如下。重新编译生成env镜像存入flash中,然后重新启动。
如下图定义ethaddr环境变量属性
在这里插入图片描述
uboot启动时提示MAC定义冲突的警告,从之前的流程分析这里会优先使用env的MAC地址
在这里插入图片描述
系统启动后如下MAC地址为env定义的ethaddr,验证成功。
在这里插入图片描述

来源地址:https://blog.csdn.net/yechongbinbin/article/details/128295501

--结束END--

本文标题: 【嵌入式linux】修改网口MAC地址

本文链接: https://www.lsjlt.com/news/388800.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 【嵌入式linux】修改网口MAC地址
    使用带有网络功能的设备时,如果局域网内可能会连接很多台设备,为了保证网络通信正常,要确保每台设备的硬件MAC地址都不相同,一般在批量生产的时候可以根据产品序列号(sn号)固化每台设备的MAC地址,防止...
    99+
    2023-09-01
    linux 嵌入式 c语言
  • windows 下修改网卡MAC地址
    一、直接修改   打开网络连接,在“本地连接”的小电脑图标,右键打开“属性”。 点击上图的配置,在下图选择“Network Address”,然后在...
    99+
    2023-05-23
    MAC 网卡 地址
  • Linux系统如何修改mac地址
    今天就跟大家聊聊有关Linux系统如何修改mac地址,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。MAC(Media Access Control, 介质访问控制),或称为 MAC位...
    99+
    2023-06-28
  • Ubuntu如何修改网卡MAC地址
    这篇文章主要为大家展示了“Ubuntu如何修改网卡MAC地址”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Ubuntu如何修改网卡MAC地址”这篇文章吧。修改网卡MAC地址的方法sudo&nbs...
    99+
    2023-06-27
  • Linux系统中如何修改MAC地址
    小编给大家分享一下Linux系统中如何修改MAC地址,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!环境Centos7.7 MinimalGNU MAC chang...
    99+
    2023-06-27
  • Win10如何修改网卡Mac物理地址
    这篇文章主要介绍了Win10如何修改网卡Mac物理地址,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、Win10网卡物理地址怎么查?首先使用 Win+R 组合快捷键打开 运...
    99+
    2023-06-28
  • linux可不可以修改设备mac地址
    这篇文章主要介绍“linux可不可以修改设备mac地址”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“linux可不可以修改设备mac地址”文章能帮助大家解决问题。 ...
    99+
    2023-03-10
    linux mac
  • 如何修改电脑mac地址
    本篇文章为大家展示了如何修改电脑mac地址,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。导读mac地址又称为硬件地址或者物理地址,指的是局域网中的每一台计算机中固化在适配器的ROM中的地址,第二层数...
    99+
    2023-06-05
  • 怎么修改vps的mac地址
    要修改VPS的MAC地址,您需要登录到VPS的操作系统中,并进行以下操作:1. 打开终端或命令提示符窗口,以管理员权限运行。2. 输入以下命令来查看当前的网络接口和MAC地址:- 在Windows上,输入`ipconfig /all`。...
    99+
    2023-08-11
    vps
  • win11修改mac地址的方法
    查看物理地址 【Win+R】输入【cmd】,进入命令窗口在命令窗口输入ipconfig/all按回车,在显示结果中可以看到以太网物理地址,也即是你的网卡的mac地址。 然后进入设置,选择【网络和internet】,选择【更多网络适配器选项】...
    99+
    2023-08-17
    网络
  • 云服务器修改mac地址
    如果您的云服务器使用Mac OS系统,则可以使用以下方法来修改Mac地址: 在Mac地址列表中,选中您想要进行修改的Mac文件。 打开Mac地址列表。 点击Mac地址列表中的Mac地址。 在地址栏中输入您想要进行修改的Mac地址。 注...
    99+
    2023-10-26
    地址 服务器 mac
  • Linux中怎么更改MAC地址
    这篇文章主要介绍“Linux中怎么更改MAC地址”,在日常操作中,相信很多人在Linux中怎么更改MAC地址问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Linux中怎么更改MAC地址”的疑惑有所帮助!接下来...
    99+
    2023-06-05
  • Linux下怎么更改网卡的MAC物理地址
    这篇文章主要讲解了“Linux下怎么更改网卡的MAC物理地址”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux下怎么更改网卡的MAC物理地址”吧!有些地方是把网络地址和网卡物理地址绑定...
    99+
    2023-06-10
  • WinXP系统修改网卡MAC地址图文教程
    一般来说很多软件或是路由器都绑定了MAC地址,特别是一些软件需要绑定到mac地址,换一台电脑之后,因为mac地址的变动,而引起软件无法使用,这时我们可以需要把当前电脑的mac地址修改成和能使用电脑的mac地址一样就可以使...
    99+
    2023-06-07
    WinXP系统 修改网卡MAC地址 地址 网卡 MAC 系统 图文
  • linux中修改网关地址的方法
    linux中修改网关地址的方法:1.打开终端;2.输入“ifconfig”命令查看网卡信息;3.打开/etc/sysconfig/network-scripts/ifcfg-eth0配置文件;4.修改文件中对应的网关地址配置;5.输入“se...
    99+
    2024-04-02
  • 云主机如何修改mac地址
    在云主机中修改mac地址的方法:1.远程登录云主机;2.控制面板点击“网络和Internet”;3.点击“网络和共享中心”选项;4.点击左侧"更改适配器设置"选项;5.右键“本地连接”,选择属性;6.选择“Microso...
    99+
    2024-04-02
  • 怎么在Linux中更改MAC地址
    这篇文章主要介绍怎么在Linux中更改MAC地址,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!在 Linux 中更改 MAC 地址让我们一步步来:查找你的 MAC 地址和网络接口让我们找出一些关于 Linux 中网卡...
    99+
    2023-06-16
  • mac修改ip地址后无法上网如何解决
    如果您在Mac上修改了IP地址后无法上网,可以尝试以下几个解决方法:1. 检查网络连接:确保您的Mac已连接到正确的网络,并且网络连...
    99+
    2023-10-10
    mac
  • 修改公网IP和mac地址的方法是什么
    这期内容当中小编将会给大家带来有关修改公网IP和mac地址的方法是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。最近本人需要用php写一个模拟程序,该程序需要不断变化公网IP地址,以及修改本机的mac...
    99+
    2023-06-12
  • 怎么在WinXP系统中修改网卡的MAC地址
    这篇文章将为大家详细讲解有关怎么在WinXP系统中修改网卡的MAC地址,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。mac地址修改方法第1步:单击打开XP的左下角的开始菜单,在打开的开始菜单...
    99+
    2023-06-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作