Linux C 常用网卡操作 (收集|整理)

实现静态IP地址,掩码,网关的设置

#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <error.h>
#include <net/route.h>

int SetIfAddr(char *ifname, char *Ipaddr, char *mask,char *gateway)
{
    int fd;
    int rc;
    struct ifreq ifr; 
    struct sockaddr_in *sin;
    struct rtentry  rt;

    fd = socket(AF_INET, SOCK_DGRAM, 0);
    if(fd < 0)
    {
            perror("socket   error");     
            return -1;     
    }
    memset(&ifr,0,sizeof(ifr)); 
    strcpy(ifr.ifr_name,ifname); 
    sin = (struct sockaddr_in*)&ifr.ifr_addr;     
    sin->sin_family = AF_INET;  

    //ipaddr
    if(inet_aton(Ipaddr,&(sin->sin_addr)) < 0)   
    {     
        perror("inet_aton   error");     
        return -2;     
    }    

    if(ioctl(fd,SIOCSIFADDR,&ifr) < 0)   
    {     
        perror("ioctl   SIOCSIFADDR   error");     
        return -3;     
    }

    //netmask
    if(inet_aton(mask,&(sin->sin_addr)) < 0)   
    {     
        perror("inet_pton   error");     
        return -4;     
    }    
    if(ioctl(fd, SIOCSIFNETMASK, &ifr) < 0)
    {
        perror("ioctl");
        return -5;
    }

    //gateway
    memset(&rt, 0, sizeof(struct rtentry));
    memset(sin, 0, sizeof(struct sockaddr_in));
    sin->sin_family = AF_INET;
    sin->sin_port = 0;
    if(inet_aton(gateway, &sin->sin_addr)<0)
    {
       printf ( "inet_aton error\n" );
    }
    memcpy ( &rt.rt_gateway, sin, sizeof(struct sockaddr_in));
    ((struct sockaddr_in *)&rt.rt_dst)->sin_family=AF_INET;
    ((struct sockaddr_in *)&rt.rt_genmask)->sin_family=AF_INET;
    rt.rt_flags = RTF_GATEWAY;
    if (ioctl(fd, SIOCADDRT, &rt)<0)
    {
        zError( "ioctl(SIOCADDRT) error in set_default_route\n");
        close(fd);
        return -1;
    }
    close(fd);
    return rc;
}

获取网卡信息

方法一: 通过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;  
} 

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

其他:

linux编程获取本机IP地址的三种方法:

  1. 通过gethostname()和gethostbyname()
  2. 通过枚举网卡,API接口可查看man netdevice,,, 关注,getifaddrs(&ifAddrStruct);
  3. 打开一个对外界服务器的网络连接,通过getsockname()反查自己的IP

其他,参见:linux编程获取本机网络相关参数

猜你喜欢

转载自blog.csdn.net/guozhongwei1/article/details/82144580