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


    生产上的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 ",
    (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 ",
    (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 ", (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 ",
    (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信息。这下应该没啥问题了。

    代码稍后。

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

    后期一定优化,下班了。

  • 相关阅读:
    【转载】JavaScript变量: 变量命名原则
    【转载】mysql运行报【The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone...】的解决方法
    Java Web 环境搭建
    原生JS消息提示插件Message.js
    SQL Server 参数嗅探问题
    根据表名和列名获取关联index的创建脚本
    mongodb快速均衡导入数据
    index optimize
    PG Foreign key 外键
    无密码登陆
  • 原文地址:https://www.cnblogs.com/pangkr-linux/p/10420015.html
Copyright © 2020-2023  润新知