<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    Linux下利用ioctl函數獲取網卡信息

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接

    linux下的ioctl函數原型如下:

    #include <sys/ioctl.h>

    int ioctl(int handle, int cmd, [int *argc, int argv])

    函數成功返回0,失敗返回-1.

    其相關命令接口如下:

     

    類別 Request 說明 數據類型 套 接 口 SIOCATMARK SIOCSPGRP SIOCGPGRP 是否位于帶外標記 設置套接口的進程ID 或進程組ID 獲取套接口的進程ID 或進程組ID int int int 文 件 FIONBIO FIOASYNC FIONREAD FIOSETOWN FIOGETOWN 設置/ 清除非阻塞I/O 標志 設置/ 清除信號驅動異步I/O 標志 獲取接收緩存區中的字節數 設置文件的進程ID 或進程組ID 獲取文件的進程ID 或進程組ID int int int int int 接 口 SIOCGIFCONF SIOCSIFADDR SIOCGIFADDR SIOCSIFFLAGS SIOCGIFFLAGS SIOCSIFDSTADDR SIOCGIFDSTADDR SIOCGIFBRDADDR SIOCSIFBRDADDR SIOCGIFNETMASK SIOCSIFNETMASK SIOCGIFMETRIC SIOCSIFMETRIC SIOCGIFMTU SIOCxxx 獲取所有接口的清單 設置接口地址 獲取接口地址 設置接口標志 獲取接口標志 設置點到點地址 獲取點到點地址 獲取廣播地址 設置廣播地址 獲取子網掩碼 設置子網掩碼 獲取接口的測度 設置接口的測度 獲取接口MTU (還有很多取決于系統的實現) struct ifconf struct ifreq struct ifreq struct ifreq struct ifreq struct ifreq struct ifreq struct ifreq struct ifreq struct ifreq struct ifreq struct ifreq struct ifreq struct ifreq ARP SIOCSARP SIOCGARP SIOCDARP 創建/ 修改ARP 表項 獲取ARP 表項 刪除ARP 表項 struct arpreq struct arpreq struct arpreq 路 由 SIOCADDRT SIOCDELRT 增加路徑 刪除路徑 struct rtentry struct rtentry        

     

     

    在這里我們需要用到的結構體

    #include<netinet/in.h>

    struct sockaddr_in { short sin_family; /* Address family */ unsigned short sin_port; /* Port number */ struct in_addr sin_addr; /* Internet address */ unsigned char sin_zero[8]; /* Same size as struct sockaddr */ };

    #include <net/if.h>

    struct ifreq
    {
    #define IFHWADDRLEN 6
    union
    {
    charifrn_name[IFNAMSIZ]; 
    } ifr_ifrn;

    union {
    structsockaddr ifru_addr;
    structsockaddr ifru_dstaddr;
    structsockaddr ifru_broadaddr;
    structsockaddr ifru_netmask;
    struct sockaddr ifru_hwaddr;
    shortifru_flags;
    intifru_ivalue;
    intifru_mtu;
    struct ifmap ifru_map;
    charifru_slave[IFNAMSIZ]; 
    charifru_newname[IFNAMSIZ];
    void __user * ifru_data;
    structif_settings ifru_settings;
    } ifr_ifru;
    };

    #define ifr_name ifr_ifrn.ifrn_name 
    #define ifr_hwaddr ifr_ifru.ifru_hwaddr 
    #defineifr_addr ifr_ifru.ifru_addr 
    #defineifr_dstaddr ifr_ifru.ifru_dstaddr 
    #defineifr_broadaddr ifr_ifru.ifru_broadaddr 
    #defineifr_netmask ifr_ifru.ifru_netmask
    #defineifr_flags ifr_ifru.ifru_flags 
    #defineifr_metric ifr_ifru.ifru_ivalue
    #defineifr_mtu ifr_ifru.ifru_mtu
    #define ifr_map ifr_ifru.ifru_map
    #define ifr_slave ifr_ifru.ifru_slave
    #defineifr_data ifr_ifru.ifru_data 
    #define ifr_ifindex ifr_ifru.ifru_ivalue
    #define ifr_bandwidth ifr_ifru.ifru_ivalue 
    #define ifr_qlen ifr_ifru.ifru_ivalue
    #define ifr_newname ifr_ifru.ifru_newname
    #define ifr_settings ifr_ifru.ifru_setting

    ioctl函數能獲取到IP地址、子網掩碼、廣播地址、硬件MAC地址等信息,至于網關及路由表比較復雜,在此不討論。

    具體代碼如下:(測試通過)

    #include <stdio.h>

    #include <stdlib.h>

    #include <net/if.h>

    #include <unistd.h>

    #include <sys/ioctl.h>

    #include <arpa/inet.h>

    #include <sys/stat.h>

    #include <sys/types.h>

    #include <errno.h>

    #include <fcntl.h>

    #include <netinet/in.h>

    #include <net/route.h>

    #include <string.h>

    #include <net/if_arp.h>

     

    int main()

    {

       struct sockaddr_in *sin;

       struct ifreq ifr;

       FILE *dns;

       FILE *gw;

       char *ip = new char(16);

       char *netmask = new char(16);

       char *broadcast = new char(16);

       //char *ip = (char *)malloc(16);

       char *mac = new  char(32);

       //char *mac = (char *)malloc(32);

       int socket_fd;

     

           if((socket_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){

                   perror("socket");

                   exit(1);

           }

     

           memset(&ifr, 0, sizeof(ifr));

           strcpy(ifr.ifr_name, "eth0");

           memset(&sin, 0, sizeof(sin));

    //獲取IP地址

           if(ioctl(socket_fd, SIOCGIFADDR, &ifr) != -1){

                   sin = (struct sockaddr_in *)&ifr.ifr_addr;

                   strcpy(ip, inet_ntoa(sin->sin_addr));

                   printf("IP address is %s\n", ip);

           }

    //獲取廣播地址

     

           if(ioctl(socket_fd, SIOCGIFBRDADDR, &ifr) != -1){

                   sin = (struct sockaddr_in *)&ifr.ifr_broadaddr;

                   strcpy(broadcast, inet_ntoa(sin->sin_addr));

                   printf("Broadcast is %s\n", broadcast);

           }

    //獲取子網掩碼

     

           if(ioctl(socket_fd, SIOCGIFNETMASK, &ifr) != -1){

                   sin = (struct sockaddr_in *)&ifr.ifr_broadaddr;

                   strcpy(netmask, inet_ntoa(sin->sin_addr));

                   printf("Net-mask is %s\n", netmask);

           }

    //獲取硬件MAC地址

     

           if(ioctl(socket_fd, SIOCGIFHWADDR, &ifr) != -1){

                   sin = (struct sockaddr_in *)&ifr.ifr_netmask;

                   sprintf(mac, "%02x:%02x:%02x:%02x:%02x:%02x",

                   (unsigned char)ifr.ifr_netmask.sa_data[0],

                   (unsigned char)ifr.ifr_netmask.sa_data[1],

                   (unsigned char)ifr.ifr_netmask.sa_data[2],

                   (unsigned char)ifr.ifr_netmask.sa_data[3],

                   (unsigned char)ifr.ifr_netmask.sa_data[4],

                   (unsigned char)ifr.ifr_netmask.sa_data[5]);

                   printf("Mac address is %s\n", mac);

           }

       return 0;

    }

     

    至于獲取網關以及DNS,我是通過相關命令獲得的。

    主要代碼如下:

    //獲取網關,利用route -n 命令可以看到相關的網關。連接標志是‘UG’

    if(gw_fd = popen("route -n | grep 'UG'", "r")){

       fread(temp,1,128, gw_fd);

       sscanf(temp, "%*s%s", szNetGate);

       printf("Gateway is %s\n", szNetGate);

    }

    //獲取DNS;一般DNS保存在/etc/reslov.conf文件中。具體獲得方法要根據實際情況而定。

    我的配置文件中是這樣的

    root@nill:/home/arm-none-linux# cat /etc/resolv.conf

     

    # Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)

    #     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN

    nameserver 202.96.134.133  

    上面的202.96.134.133就是我需要獲取的主DNS,沒有備用DNS

    if(dns_fd = popen("cat /etc/reslov.conf | grep 'nameserver'", "r")){

       fread(temp,1,128, gw_fd);

       sscanf(temp, "%*s%s%*s%s", szDNS1,szDNS2);

       printf("DNS1 is %s",szDNS1);

       printf("DNS2is %s", szDNS2);

    }

     

    轉載地址:http://5375342.blog.51cto.com/5365342/1209335

    相關地址:http://blog.csdn.net/bailyzheng/article/details/7489656

    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全