ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【填坑2】获取设备所有网卡的mac地址

2019-02-22 18:51:01  阅读:268  来源: 互联网

标签:char ifr 填坑 unsigned 网卡 mac hwaddr data 02x


生产上的bug:

由于用户删除网卡之后未作重启动作,导致网卡不连续,ip a查看网卡信息前面的序号不连续。

比如:正常是123456,删除4之后成了123 56 。

获取机器所有网卡的mac地址,5 6号网卡信息未读到。

代码1:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/if_ether.h>
#include <net/if.h>

int getMacInfo()
{
struct ifreq ifr;

int sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == -1) {
return -1;
}

int index = 1;
while(1) {

ifr.ifr_ifindex = index++;
if (ioctl(sock, SIOCGIFNAME, &ifr) != 0) {
close(sock);
return 0;
}

if (ioctl(sock, SIOCGIFFLAGS, &ifr) == 0) {
if (! (ifr.ifr_flags & IFF_LOOPBACK)) { // don't count loopback
if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) {

printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
(unsigned char)ifr.ifr_hwaddr.sa_data[0],
(unsigned char)ifr.ifr_hwaddr.sa_data[1],
(unsigned char)ifr.ifr_hwaddr.sa_data[2],
(unsigned char)ifr.ifr_hwaddr.sa_data[3],
(unsigned char)ifr.ifr_hwaddr.sa_data[4],
(unsigned char)ifr.ifr_hwaddr.sa_data[5]);
}
}
}
}

close(sock);
return -1;
}

int main(int argc, char **argv)
{
getMacInfo();
return 0;
}

 

又改了一版,强制循环读20次

代码2:

int getMacInfo()
{
struct ifreq ifr;

int sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == -1) {
return -1;
}

int index = 1;
while(index<21) {

ifr.ifr_ifindex = index++;

if (ioctl(sock, SIOCGIFNAME, &ifr) != 0) {
continue;
}

if (ioctl(sock, SIOCGIFFLAGS, &ifr) == 0) {
if (! (ifr.ifr_flags & IFF_LOOPBACK)) { // don't count loopback
if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) {

printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
(unsigned char)ifr.ifr_hwaddr.sa_data[0],
(unsigned char)ifr.ifr_hwaddr.sa_data[1],
(unsigned char)ifr.ifr_hwaddr.sa_data[2],
(unsigned char)ifr.ifr_hwaddr.sa_data[3],
(unsigned char)ifr.ifr_hwaddr.sa_data[4],
(unsigned char)ifr.ifr_hwaddr.sa_data[5]);
}
}
}
}

close(sock);
return -1;
}

int main(int argc, char **argv)
{
getMacInfo();
return 0;
}

 

这样做不是很完美,后来又出了一版,用ioctl的SIOCGIFCONF参数

代码3:

#include <net/if.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main()
{

int i = 0;
int sockfd;
struct ifconf ifconf;
char buf[1024];
struct ifreq *ifreq;

ifconf.ifc_len = sizeof(buf);
ifconf.ifc_buf = (caddr_t)buf;

if ((sockfd=socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket");
exit(1);
}

ioctl(sockfd, SIOCGIFCONF, &ifconf);

ifreq = (struct ifreq*)buf;
printf("ifconf.ifc_len: %d sizeof(struct ifreq):%d\n", (int)ifconf.ifc_len, (int)sizeof(struct ifreq));
for (i=(ifconf.ifc_len/sizeof(struct ifreq))-1; i>=0; i--) {

if (ioctl(sockfd, SIOCGIFHWADDR, &ifreq[i]) == 0) {
printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
(unsigned char)ifreq[i].ifr_hwaddr.sa_data[0],
(unsigned char)ifreq[i].ifr_hwaddr.sa_data[1],
(unsigned char)ifreq[i].ifr_hwaddr.sa_data[2],
(unsigned char)ifreq[i].ifr_hwaddr.sa_data[3],
(unsigned char)ifreq[i].ifr_hwaddr.sa_data[4],
(unsigned char)ifreq[i].ifr_hwaddr.sa_data[5]);
}

}
close(sockfd);
return 0;
}

这一版获取的mac信息也不全。

网上找的原因:系统接口,通过ioctl  SIOCGIFCONF来获取网卡信息有个问题,就是当我的网卡没能分配到ip时,就会获取不到该网卡信息

 

最后定了一版,就是先从系统文件/proc/net/dev中读出所有的devName,再调用ioctl接口获取mac信息。这下应该没啥问题了。

代码稍后。

 

由于粘的代码,缩进丢失,博客园不会添加代码块,还有本人比较懒。先凑合看看吧。

后期一定优化,下班了。

标签:char,ifr,填坑,unsigned,网卡,mac,hwaddr,data,02x
来源: https://www.cnblogs.com/pangkr-linux/p/10420015.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有