【编程笔记】获取主机mac地址、ip地址

一、前言

主机的IP地址一般是可能会随着时间变化,例如DHCP的网络中会在不同的时间段分配不同的地址,而主机的MAC地址理论上是全球唯一的硬件地址,但是在虚拟化环境中,是可以被被伪造或更改。因此,MAC地址、IP地址并不能相对唯一的标识某一台主机设备,对于应用程序而言,更好的做法可能是使用应用程序级别的身份验证和授权机制,或者为每台主机生成一个唯一的ID(如UUID)并存储在安全的地方(如注册表、文件系统或数据库中。当然,本文只是简单学习如果编程在linux系统中获取MAC_IP地址对。

二、获取MAC地址和IP地址

1、有线网卡、无线网卡常见名称

1) 有线网卡名称

  • eth:例如 eth0, eth1
  • en:例如 enp0s3, ens33
  • em:例如 em1, em2
  • p:例如 p1p1,p2p1
  • br:例如 br-lan(桥接接口)
  • usb:例如 usb0(USB 网络设备)
  • can:例如 can0(CAN总线接口)

3)无线网卡名称

  • wlan:例如 wlan0, wlan1
  • wl:例如 wlp2s0, wlp3s0
  • wlp:例如 wlp2s0, wlp3s0
  • wlo:例如 wlo1, wlo2
  • ra:例如 ra0(Realtek 无线网卡)
  • ath:例如 ath0(Atheros 无线网卡)
  • wlan:例如 wlan0(通用无线网卡)
  • sta:例如 sta0(站模式无线网卡)
  • ap:例如 ap0(接入点模式无线网卡)

2、判断网卡名称

这里采用列举的方式检索有线、无线常见的网卡名称,使用is_valid_interface函数来判断

int is_valid_interface(const char *interface_name) {
    // 排除 lo 网卡
    if (strcmp(interface_name, "lo") == 0) {
        return 0;
    }

    // 检查是否为 eth 或 en 开头的有线网卡
    if (strncmp(interface_name, "eth", 3) == 0 || strncmp(interface_name, "en", 2) == 0 ||
        strncmp(interface_name, "em", 2) == 0 || strncmp(interface_name, "p", 1) == 0 ||
        strncmp(interface_name, "br", 2) == 0 || strncmp(interface_name, "usb", 3) == 0 ||
        strncmp(interface_name, "can", 3) == 0) {
        return 1;
    }

    // 检查是否为 wlan 或 wl 开头的无线网卡
    if (strncmp(interface_name, "wlan", 4) == 0 || strncmp(interface_name, "wl", 2) == 0 ||
        strncmp(interface_name, "wlp", 3) == 0 || strncmp(interface_name, "wlo", 3) == 0 ||
        strncmp(interface_name, "ra", 2) == 0 || strncmp(interface_name, "ath", 3) == 0 ||
        strncmp(interface_name, "sta", 3) == 0 || strncmp(interface_name, "ap", 2) == 0) {
        return 1;
    }

    return 0;
}

3、查找可用网卡

这里使用find_available_interface函数来遍历查找符合条件的网卡并打印MAC地址、IP地址

int find_available_interface(char *interface_name, char *mac_str, char *ip_str) {
    struct ifaddrs *ifaddr, *ifa;
    int sockfd;

    if (getifaddrs(&ifaddr) == -1) {
        perror("getifaddrs");
        return 0;
    }

    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        perror("socket");
        freeifaddrs(ifaddr);
        return 0;
    }

    for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
        if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_INET)
            continue;

        // 检查是否为有效的有线或无线网卡
        if (!is_valid_interface(ifa->ifa_name)) {
            continue;
        }

        printf("Checking interface: %s\n", ifa->ifa_name);  // 添加日志

        // 获取接口标志
        struct ifreq ifr;
        strncpy(ifr.ifr_name, ifa->ifa_name, IFNAMSIZ);

        // 获取接口标志
        if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) == -1) {
            perror("ioctl SIOCGIFFLAGS");
            continue;
        }

        // 检查接口是否处于运行状态
        if (!(ifr.ifr_flags & IFF_UP)) {
            continue;
        }

        // 获取接口硬件地址
        if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) == -1) {
            perror("ioctl SIOCGIFHWADDR");
            continue;
        }

        // 格式化 MAC 地址
        snprintf(mac_str, 18, "%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]);
        printf("MAC Address: %s\n", mac_str);  // 添加日志

        // 查找对应的 IPv4 地址
        struct sockaddr_in *ipv4 = (struct sockaddr_in *)ifa->ifa_addr;
        inet_ntop(AF_INET, &(ipv4->sin_addr), ip_str, INET_ADDRSTRLEN);
        printf("IP Address: %s\n", ip_str);  // 添加日志
    }

    close(sockfd);
    freeifaddrs(ifaddr);
    return 0;
}

三、打印MAC、IP地址

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值