• Linux获取网络接口信息


    linux获取网络接口信息需要用到的函数为ioctl(),结构体struct ifreq,struct ifconf

    1.ioctl()函数原型及作用

    1 #include <sys/ioctl.h>
    2  
    3 int ioctl(int d, int request, ...);
    4 
    5 //参数
    6 //int d:是一个文件描述符
    7 //int request :表示要请求的信息。如IP地址、网络掩码等
    8 //......:可变参数,根据request而定

    下面是ioctl请求的request参数以及arg地址必须指向的数据类型:

    2.struct ifreq结构体

      这个结构定义在include/net/if.h,用来配置ip地址,激活接口,配置MTU等接口信息的

     1  /* Interface request structure used for socket ioctl's.  All interface
     2     ioctl's must have parameter definitions which begin with ifr_name.
     3     The remainder may be interface specific.  */
     4  
     5 struct ifreq
     6 {
     7 # define IFHWADDRLEN    6
     8 # define IFNAMSIZ   IF_NAMESIZE
     9      union
    10        {
    11      char ifrn_name[IFNAMSIZ];   /* Interface name, e.g. "en0".  */
    12        } ifr_ifrn;
    13  
    14      union
    15        {
    16      struct sockaddr ifru_addr;
    17      struct sockaddr ifru_dstaddr;
    18      struct sockaddr ifru_broadaddr;
    19      struct sockaddr ifru_netmask;
    20      struct sockaddr ifru_hwaddr;
    21      short int ifru_flags;
    22      int ifru_ivalue;
    23      int ifru_mtu;
    24      struct ifmap ifru_map;
    25      char ifru_slave[IFNAMSIZ];  /* Just fits the size */
    26      char ifru_newname[IFNAMSIZ];
    27      __caddr_t ifru_data;
    28        } ifr_ifru;
    29    };
    30  # define ifr_name   ifr_ifrn.ifrn_name  /* interface name   */
    31  # define ifr_hwaddr ifr_ifru.ifru_hwaddr    /* MAC address      */
    32  # define ifr_addr   ifr_ifru.ifru_addr  /* address      */
    33  # define ifr_dstaddr    ifr_ifru.ifru_dstaddr   /* other end of p-p lnk */
    34  # define ifr_broadaddr  ifr_ifru.ifru_broadaddr /* broadcast address    */
    35  # define ifr_netmask    ifr_ifru.ifru_netmask   /* interface net mask   */
    36  # define ifr_flags  ifr_ifru.ifru_flags /* flags        */
    37  # define ifr_metric ifr_ifru.ifru_ivalue    /* metric       */
    38  # define ifr_mtu    ifr_ifru.ifru_mtu   /* mtu          */
    39  # define ifr_map    ifr_ifru.ifru_map   /* device map       */
    40  # define ifr_slave  ifr_ifru.ifru_slave /* slave device     */
    41  # define ifr_data   ifr_ifru.ifru_data  /* for use by interface */
    42  # define ifr_ifindex    ifr_ifru.ifru_ivalue    /* interface index      */
    43  # define ifr_bandwidth  ifr_ifru.ifru_ivalue    /* link bandwidth   */
    44  # define ifr_qlen   ifr_ifru.ifru_ivalue    /* queue length     */
    45  # define ifr_newname    ifr_ifru.ifru_newname   /* New name     */
    46  # define _IOT_ifreq _IOT(_IOTS(char),IFNAMSIZ,_IOTS(char),16,0,0)
    47  # define _IOT_ifreq_short _IOT(_IOTS(char),IFNAMSIZ,_IOTS(short),1,0,0)
    48  # define _IOT_ifreq_int _IOT(_IOTS(char),IFNAMSIZ,_IOTS(int),1,0,0)

    3.struct ifconf

      ifreq包含在ifconf结构中。而ifconf结构通常是用来保存所有接口的信息的。

     1  /* Structure used in SIOCGIFCONF request.  Used to retrieve interface
     2     configuration for machine (useful for programs which must know all
     3     networks accessible).  */
     4  
     5  struct ifconf
     6    {
     7      int ifc_len;            /* Size of buffer.  */
     8      union
     9        {
    10      __caddr_t ifcu_buf;
    11      struct ifreq *ifcu_req;
    12        } ifc_ifcu;
    13    };
    14  # define ifc_buf    ifc_ifcu.ifcu_buf   /* Buffer address.  */
    15  # define ifc_req    ifc_ifcu.ifcu_req   /* Array of structures.  */
    16  # define _IOT_ifconf _IOT(_IOTS(struct ifconf),1,0,0,0,0) /* not right */
    17  #endif  /* Misc.  */

    下面程序是获取本机的IP地址

     1 #include <stdio.h>
     2 #include <sys/socket.h>
     3 #include <string.h>
     4 #include <sys/types.h>
     5 #include <netinet/in.h>
     6 #include <sys/ioctl.h>
     7 #include <net/if.h>
     8 #include <arpa/inet.h>
     9 
    10 #ifndef IFNAMESZ
    11 #define IFNAMESZ 16
    12 #endif
    13 
    14 int main(int argc, char *argv[])
    15 {
    16     if (argc != 2) {
    17         printf("using %s <ETH_NAME>
    ", argv[0]);
    18         return 0;
    19     }   
    20 
    21     int sock = 0;
    22     struct sockaddr_in sin;
    23     struct ifreq ifr;//用来保存接口的信息
    24 
    25     sock = socket(AF_INET, SOCK_DGRAM, 0); 
    26     if (sock == -1) {
    27         perror("socket");
    28         return 1;
    29     }   
    30     memcpy(ifr.ifr_name, argv[1], IFNAMESZ);
    31     ifr.ifr_name[IFNAMESZ - 1] = '';
    32 
    33     if (ioctl(sock,  SIOCGIFADDR, &ifr) == 0) { //SIOCGIFADDR 获取接口地址
    34         memcpy(&sin, &ifr.ifr_addr, sizeof(sin));   //将获得地址拷贝到 sockaddr_in 结构体中
    35         printf("Ip: %s
    ", inet_ntoa(sin.sin_addr)); 
    36     }   
    37 
    38     if (ioctl(sock, SIOCGIFNETMASK, &ifr) == 0) {
    39         memcpy(&sin, &ifr.ifr_netmask, sizeof(sin));
    40         printf("netmask: %s
    ", inet_ntoa(sin.sin_addr)); 
    41     }   
    42     close(sock);
    43 
    44     return 0;    
    45 }

    运行结果如下:

  • 相关阅读:
    n个数字相加
    爬取编程常用词汇,保存为Excel
    Python对 Excel 的常用操作
    Python对Redis增删改查
    Python对MySql增删改查
    Python对MongoDB增删改查
    MySql事务的简单使用
    Python-判断回文
    Pyhton 连接数据库
    PyCharm设置完自动上传,却不会自动上传任何内容
  • 原文地址:https://www.cnblogs.com/wenqiang/p/5036040.html
Copyright © 2020-2023  润新知