知识库

个人知识管理

用户工具

站点工具


c和cpp:linux下如何获得特定网卡信息

Linux下如何获得特定网卡信息

C代码

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
 
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
 
#include <arpa/inet.h>
#include <netinet/in.h>
#include <net/if.h>
/**
 * 网卡设备信息结构体
 */
struct NetDevice
{
    // 网卡名
    char name[64];
    // 网卡物理地址
    char mac[64];
    // 网卡IPv4地址
    char ip[64];
    // 广播地址
    char broadcast[64];
    // 子网掩码地址
    char mask[64];
};
/**
 * 获取当前网络设备信息
 * @param device 需要获取的网卡设备名
 * @param info 存放网卡设备信息的结构体
 * @return 成功返回0,出现错误返回非0
 */
int getDeviceInfo(const char* device, struct NetDevice* info)
{
    int sockfd;
    int code = 0;
    struct sockaddr_in sin;
    struct ifreq ifr;
    unsigned char mac_addr[16];
 
    // 初始化socket
    sockfd=socket(AF_INET, SOCK_DGRAM, 0);
    if(sockfd == -1)
    {
        perror("socket error");
        code = -1;
        return code;
    }
 
    strncpy(ifr.ifr_name, device, strlen(device));
    if ( snprintf(info->name, sizeof(info->name), "%s", device) < 0 )
    {
        perror("snprintf error\n");
        code =  -2;
    }
 
    //获取网卡地址, 转化为可读形式
    if(ioctl(sockfd, SIOCGIFHWADDR, &ifr) <0 )
    {
        perror("ioctl error\n");
        code = -3;
    } else
    {
        memcpy(mac_addr, ifr.ifr_hwaddr.sa_data, 6);
        if ( snprintf(info->mac, sizeof(info->mac), "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", mac_addr[0], mac_addr[1],
                      mac_addr[2], mac_addr[3],
                      mac_addr[4], mac_addr[5]) < 0 )
        {
            perror("snprintf error\n");
            code = -2;
        }
    }
 
    //获取IP地址, 转化为可读形式
    if(ioctl(sockfd, SIOCGIFADDR, &ifr)<0) {
        perror("ioctl error\n");
        code = -3;
    } else
    {
        memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
        if ( snprintf(info->ip, sizeof(info->ip), "%s", inet_ntoa(sin.sin_addr)) < 0 )
        {
            perror("snprintf error\n");
            code = -2;
        }
    }
 
    //获取广播地址, 转化为可读形式
    if(ioctl(sockfd, SIOCGIFBRDADDR, &ifr)<0)
    {
        perror("ioctl error\n");
        code = -3;
    } else
    {
        memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
        if ( snprintf(info->broadcast, sizeof(info->broadcast), "%s", inet_ntoa(sin.sin_addr)) < 0 )
        {
            perror("snprintf error\n");
            code = -2;
        }
    }
 
    //获取并打印子网掩码
    if(ioctl(sockfd,SIOCGIFNETMASK,&ifr)<0) {
        perror("ioctl error\n");
        code = -3;
    } else
    {
        memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
        if ( snprintf(info->mask, sizeof(info->mask), "%s", inet_ntoa(sin.sin_addr)) < 0 )
        {
            perror("snprintf error\n");
            code = -2;
        }
    }
 
    close(sockfd);
 
    return code;
}

测试程序

int main()
{
    struct NetDevice* info = (struct NetDevice*)malloc(sizeof(struct NetDevice));
    memset(info, 0, sizeof(struct NetDevice));
    int r = getDeviceInfo("wlan0", info);
 
    printf("name:\t%s\n", info->name);
    printf("ip:\t%s\n", info->ip);
    printf("mac:\t%s\n", info->mask);
    printf("broadcast:\t%s\n", info->broadcast);
    printf("mask:\t%s\n", info->mask);
    free(info);
 
    return 0;
}

测试结果

name:   wlan0
ip: 192.168.0.108
mac:    255.255.255.0
broadcast:  192.168.0.255
mask:   255.255.255.0
c和cpp/linux下如何获得特定网卡信息.txt · 最后更改: 2019/09/11 00:49 (外部编辑)