linux通过c语言接口获取网卡信息

本文介绍两种在Linux环境下检查与列举网卡信息的方法:一是利用ioctl函数通过SIOCGIFCONF请求获取网卡配置;二是采用getifaddrs函数检查特定网卡状态并列出所有网卡信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

方法一 通过ioctl的SIOCGIFCONF
实例1. 检查特定的网卡是否存在

// ppp、wifi是否正常
static int check_ppp_wifi (int wifi_switch) 
{   
    struct ifreq ifr;   
    struct ifconf ifc; 

    char buf[256];      
    int success = 0;    
    int wifi_exist = 0; 
    int ppp_exist = 0;  
    int ret = -1;
    int sock = -1;
    int count = 0; 

    if (wifi_switch == 0)       
        wifi_exist = 1; 
        sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);     
        if (sock == -1) {       
            APP_LogPrintf(ALM_ERROR, "socket error\n");         
            goto out;   
        }   

        ifc.ifc_len = sizeof(buf);      
        ifc.ifc_buf = buf;      
        if (ioctl(sock, SIOCGIFCONF, &ifc) == -1) {         
            APP_LogPrintf(ALM_ERROR,"ioctl error\n");       
            goto out;   
        }   

        struct ifreq* it = ifc.ifc_req;     
        const struct ifreq* const end = it + (ifc.ifc_len / sizeof(struct ifreq));          

        for (; it != end; ++it) {       
        strcpy(ifr.ifr_name, it->ifr_name);         
        if (ioctl(sock, SIOCGIFFLAGS, &ifr) == 0) {             
            if (! (ifr.ifr_flags & IFF_LOOPBACK)) { 
                // don't count loopback                 
                if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) {                    
                    count ++ ;                      
                    unsigned char * ptr ;                   
                    ptr = (unsigned char  *)&ifr.ifr_ifru.ifru_hwaddr.sa_data[0];                   
                    if (strncmp("ppp0", ifr.ifr_name, 4) == 0) {                        
                        ppp_exist = 1;                      
                        if (wifi_exist) {   
                            ret = 0;                            
                            goto out; 
                        }                   
                    } else if (strncmp("uap0", ifr.ifr_name, 4) == 0) {                     
                        wifi_exist = 1;                     
                        if (wifi_exist) {   
                            ret = 0;                            
                            goto out; 
                        }                   
                    }               
                }  
            }       
        } else {            
            APP_LogPrintf(ALM_ERROR,"get mac info error\n");            
            goto out;       
        }   
    }  

out:
    if (-1 != sock)
        close(sock);
    return ret;
}

实例2 列举系统所有的网卡信息

#include <sys/ioctl.h>
#include <net/if.h>
#include <unistd.h>
#include <netinet/in.h>
#include <string.h>

int main()
{
    struct ifreq ifr;
    struct ifconf ifc;
    char buf[2048];
    int success = 0;

    int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
    if (sock == -1) {
        printf("socket error\n");
        return -1;
    }

    ifc.ifc_len = sizeof(buf);
    ifc.ifc_buf = buf;
    if (ioctl(sock, SIOCGIFCONF, &ifc) == -1) {
        printf("ioctl error\n");
        return -1;
    }

    struct ifreq* it = ifc.ifc_req;
    const struct ifreq* const end = it + (ifc.ifc_len / sizeof(struct ifreq));
    char szMac[64];
    int count = 0;
    for (; it != end; ++it) {
        strcpy(ifr.ifr_name, it->ifr_name);
        if (ioctl(sock, SIOCGIFFLAGS, &ifr) == 0) {
            if (! (ifr.ifr_flags & IFF_LOOPBACK)) { // don't count loopback
                if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) {
                    count ++ ;
                    unsigned char * ptr ;
                    ptr = (unsigned char  *)&ifr.ifr_ifru.ifru_hwaddr.sa_data[0];
                    snprintf(szMac,64,"%02X:%02X:%02X:%02X:%02X:%02X",*ptr,*(ptr+1),*(ptr+2),*(ptr+3),*(ptr+4),*(ptr+5));
                    printf("%d,Interface name : %s , Mac address : %s \n",count,ifr.ifr_name,szMac);
                }
            }
        }else{
            printf("get mac info error\n");
            return -1;
        }
    }
}

注意:使用的时候一定要记得关闭socket,不然可能会导致打开文件过多,程序崩溃。

方案二:通过getifaddrs()来实现
实例1 检查特定网卡

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include <ifaddrs.h>
#include <arpa/inet.h> 


int c_ifaddrs_netlink_status(const char *if_name )
{
    struct ifaddrs *ifa = NULL, *ifList;  

    if (getifaddrs(&ifList) < 0) {
        return -1;
    }

    for (ifa = ifList; ifa != NULL; ifa = ifa->ifa_next) {
        if (ifa->ifa_addr->sa_family == AF_INET) {
            if (strcmp(ifa->ifa_name, if_name) ==0) {
                if (!(ifa->ifa_flags & IFF_UP)) {
                    printf("DEVICE_DOWN\r\n");
                    freeifaddrs(ifList);
                    return 1;
                }

                if (!(ifa->ifa_flags & IFF_RUNNING)) {
                    printf("DEVICE_UNPLUGGED\r\n");
                    freeifaddrs(ifList);
                    return 2;
                }

                printf("DEVICE_LINKED\r\n");
                freeifaddrs(ifList);
                return 3;
            }
        }  
    }  

    printf(stderr, "DEVICE_NONE\r\n");
    freeifaddrs(ifList);
    return 0;
}

int main(int argc, char* argv[])
{
    int i=0;
    if (argc != 2) {
        fprintf(stderr, "usage: %s <ethname>\r\n", argv[0]);
        return -1;
    }

    i = c_ifaddrs_netlink_status(argv[1]);

    fprintf(stderr,"c_ifaddrs_netlink_status if_status = %d\n", i );
    return 0;
}

实例2 列举系统所有网卡信息

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <time.h>  
#include <sys/types.h>  
#include <sys/socket.h>  
#include <netinet/in.h>  
#include <arpa/inet.h>  
#include <ifaddrs.h>  

int main(int argc, char* argv[]) {  
    struct ifaddrs *ifc, *ifc1;  
    char ip[64] = {};  
    char nm[64] = {};  

    if(0 != getifaddrs(&ifc)) return -1;  
    ifc1 = ifc;  

    printf("iface\tIP address\tNetmask\n");  
    for (; NULL != ifc; ifc = (*ifc).ifa_next) {  
        printf("%s", (*ifc).ifa_name);  
        if (NULL != (*ifc).ifa_addr) {  
            inet_ntop(AF_INET, &(((struct sockaddr_in*)((*ifc).ifa_addr))->sin_addr), ip, 64);  
            printf("\t%s", ip);  
        } else {  
            printf("\t\t");  
        }  
        if (NULL != (*ifc).ifa_netmask) {  
            inet_ntop(AF_INET, &(((struct sockaddr_in*)((*ifc).ifa_netmask))->sin_addr), nm, 64);  
            printf("\t%s", nm);  
        } else {  
            printf("\t\t");  
        }  
        printf("\n");  
    }  

    freeifaddrs(ifc1);  
    return 0;  
}  

其他优秀博客:
http://www.cnblogs.com/lidabo/p/5344760.html

ENVI软件在遥感影像处理中扮演着至关重要的角色,其中影像的几何纠正功能对于确保影像数据的精确性至关重要。几何纠正的过程涉及调整影像坐标,使其与实际地理坐标系统一致,这一步骤对于后续的分析和制图至关重要。 参考资源链接:[ENVI遥感影像处理全面指南:预处理、信息提取与三维可视化](https://wenku.youkuaiyun.com/doc/398pr5x5h3?spm=1055.2569.3001.10343) 具体步骤如下: 1. 打开ENVI软件,导入需要进行几何纠正的遥感影像。 2. 选择相应的工具,例如“Basic Tools”菜单下的“Geometric Correction”选项。 3. 根据影像数据类型和需要达到的精度,选择合适的纠正方法。ENVI提供了多种纠正算法,包括多项式模型、共线方程、地面控制点(GCP)校正等。 4. 如果使用GCP校正,需要在影像上选择若干地面控制点,并输入这些点的实际地理坐标,作为校正的基础。 5. 进行校正参数的计算,这个过程通常涉及到解算一个或多个多项式方程,以最小化影像中的点与真实地理坐标间的偏差。 6. 使用计算得到的参数进行影像的重新采样和配准,最终输出几何校正后的影像。 7. 校正结果需要评估,一般通过比较校正前后GCP的残差来验证校正的精度和效果。 适用场景: 几何纠正广泛应用于地形变化检测、土地利用调查、城市规划、环境监测等多个领域。在这些应用场景中,影像的几何准确性直接影响到分析结果的可靠性。 为了深入学习ENVI中遥感影像几何纠正的更多细节和高级应用,推荐参考《ENVI遥感影像处理全面指南:预处理、信息提取与三维可视化》一书。该指南不仅提供了理论知识,还详细介绍了操作步骤和实际应用案例,有助于读者全面掌握几何纠正的技巧和方法。 参考资源链接:[ENVI遥感影像处理全面指南:预处理、信息提取与三维可视化](https://wenku.youkuaiyun.com/doc/398pr5x5h3?spm=1055.2569.3001.10343)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值