获取网络接口信息——ioctl()函数与结构体struct ifreq、 struct ifconf

2023-12-26 05:58

本文主要是介绍获取网络接口信息——ioctl()函数与结构体struct ifreq、 struct ifconf,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

http://blog.csdn.net/windeal3203/article/details/39320605

Linux 下 可以使用ioctl()函数 以及 结构体 struct ifreq  结构体struct ifconf来获取网络接口的各种信息。


ioctl

首先看ioctl()用法
ioctl()原型如下:
   
#include <sys/ioctl.h>
int ioctl(int fd, int request, ...);
参数:
     fd     : 文件描述符
request:  表示要请求的信息。如IP地址、网络掩码等
       ...            后面的可变参数根据request而定

比如我们请求所有网络接口的清单:
[cpp]  view plain copy
  1. struct ifconf IoCtlReq;  
  2. ...  
  3. ioctl( Sock, SIOCGIFCONF, &IoCtlReq )  

其中 IoCtlReq 是一个

与接口相关的request如下表所示( 来源: < http://baike.baidu.com/view/1081282.htm?fr=aladdin > ):
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


关于ioctl的详细解释清查阅本博其它博文

struct ifreq

结构体 struct ifreq用来保存某个接口的信息。
[cpp]  view plain copy
  1. // if.h  
  2. /* 
  3.  * Interface request structure used for socket 
  4.  * ioctl's.  All interface ioctl's must have parameter 
  5.  * definitions which begin with ifr_name.  The 
  6.  * remainder may be interface specific. 
  7.  */  
  8. struct ifreq {  
  9. #define IFHWADDRLEN 6  
  10.     union  
  11.     {  
  12.         char    ifrn_name[IFNAMSIZ];        /* if name, e.g. "en0" */  
  13.     } ifr_ifrn;  
  14.       
  15.     union {  
  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   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.         void __user *   ifru_data;  
  28.         struct  if_settings ifru_settings;  
  29.     } ifr_ifru;  
  30. };  
  31. #define ifr_name    ifr_ifrn.ifrn_name  /* interface name   */  
  32. #define ifr_hwaddr  ifr_ifru.ifru_hwaddr    /* MAC address      */  
  33. #define ifr_addr    ifr_ifru.ifru_addr  /* address      */  
  34. #define ifr_dstaddr ifr_ifru.ifru_dstaddr   /* other end of p-p lnk */  
  35. #define ifr_broadaddr   ifr_ifru.ifru_broadaddr /* broadcast address    */  
  36. #define ifr_netmask ifr_ifru.ifru_netmask   /* interface net mask   */  
  37. #define ifr_flags   ifr_ifru.ifru_flags /* flags        */  
  38. #define ifr_metric  ifr_ifru.ifru_ivalue    /* metric       */  
  39. #define ifr_mtu     ifr_ifru.ifru_mtu   /* mtu          */  
  40. #define ifr_map     ifr_ifru.ifru_map   /* device map       */  
  41. #define ifr_slave   ifr_ifru.ifru_slave /* slave device     */  
  42. #define ifr_data    ifr_ifru.ifru_data  /* for use by interface */  
  43. #define ifr_ifindex ifr_ifru.ifru_ivalue    /* interface index  */  
  44. #define ifr_bandwidth   ifr_ifru.ifru_ivalue    /* link bandwidth   */  
  45. #define ifr_qlen    ifr_ifru.ifru_ivalue    /* Queue length     */  
  46. #define ifr_newname ifr_ifru.ifru_newname   /* New name     */  
  47. #define ifr_settings    ifr_ifru.ifru_settings  /* Device/proto settings*/  



ifr_name 标识了某一接口。
可以通过ioctl获取该接口的信息。如:
   
ioctl(Sock, SIOCGIFNETMASK, &IfReq);//获取网络接口地址掩码
该代码需要先对IfReq->ifr_name赋值,然后获取与 IfReq->ifr_name向匹配的网络接口 的地址掩码



struct ifconf

结构体struct ifconf通常用来保存所有接口信息
[cpp]  view plain copy
  1. // if.h  
  2. /* 
  3.  * Structure used in SIOCGIFCONF request. 
  4.  * Used to retrieve interface configuration 
  5.  * for machine (useful for programs which 
  6.  * must know all networks accessible). 
  7.  */  
  8. struct ifconf  {  
  9.     int ifc_len;            /* size of buffer   */  
  10.     union {  
  11.         char __user *ifcu_buf;  
  12.         struct ifreq __user *ifcu_req;  
  13.     } ifc_ifcu;  
  14. };  
  15. #define ifc_buf ifc_ifcu.ifcu_buf       /* buffer address   */  
  16. #define ifc_req ifc_ifcu.ifcu_req       /* array of structures  */  


该结构体可以用来获取所哟网络接口的名字和信息(不是全部信息,是ip地址)
(图片来自: http://tech.sunplusedu.com/space/post-4064.aspx



Example:

[cpp]  view plain copy
  1. #include <sys/types.h>    
  2. #include <sys/ioctl.h>    
  3. #include <sys/socket.h>    
  4. #include <net/if.h>    
  5. #include <stdio.h>    
  6. #include <stdlib.h>    
  7. #include <unistd.h>    
  8. #include <netdb.h>    
  9. #include <string.h>    
  10. #include <fcntl.h>    
  11. #include <string.h>    
  12. #include <errno.h>  
  13. typedef uint32_t uint32;   
  14. #define MAX_IF 10  
  15. int   
  16. main()  
  17. {  
  18.     struct ifreq ifVec[MAX_IF];//用来保存所有接口  
  19.       
  20.     int sock = -1;  
  21.     if ( (sock = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 )  
  22.         fprintf(stderr, "Error:%d, cannot open RAM;\n");  
  23.       
  24.     // get if vector  
  25.     struct ifconf ioIfConf;  
  26.         ioIfConf.ifc_buf = (void *)ifVec;  
  27.         ioIfConf.ifc_len = sizeof(ifVec);  
  28.      printf("Len:%d\n", ioIfConf.ifc_len);       
  29.           
  30.     if (ioctl(sock, SIOCGIFCONF, &ioIfConf) < 0 )//获取所有网络接口信息  
  31.         fprintf(stderr, "Error:%d   ioctl IFCONF\n");  
  32.       
  33.      printf("Len:%d\n", ioIfConf.ifc_len);// 和前面到len对比,发现ioctl修改里len到大小       
  34.     //循环打印每个网络接口到信息  
  35.     {  
  36.         struct ifreq *ifPt;  
  37.         struct ifreq *ifEndPt;  
  38.         ifPt = ifVec;  
  39.         ifEndPt = (void *)((char *)ifVec + ioIfConf.ifc_len);  
  40.         for (ifPt = ifVec; ifPt < ifEndPt; ifPt++)  
  41.         {  
  42.             struct ifreq ifReq;  
  43.             if ( ifPt->ifr_addr.sa_family != AF_INET ) {  
  44.                         continue;  
  45.                     }  
  46.               
  47.             // Temp keepers of interface params...  
  48.             uint32 u32_addr, u32_mask;  
  49.               
  50.             /*  打印ip地址  */  
  51.             char ipDotBuf[16], subnetDotBuf[16], maskDotBuf[16]; // 保存点分十进制到ip地址  
  52.             u32_addr = ((struct sockaddr_in *)&ifPt->ifr_addr)->sin_addr.s_addr;  
  53.             inet_ntop(AF_INET, &u32_addr, ipDotBuf, (socklen_t )sizeof(ipDotBuf));   
  54.             printf("IP Address: %s\n", ipDotBuf);  
  55.               
  56.             /*    打印地址掩码    */  
  57.             bzero(&ifReq,sizeof(struct ifreq));    
  58.             memcpy(ifReq.ifr_name, ifPt->ifr_name, sizeof(ifReq.ifr_name));    
  59.             if (ioctl(sock, SIOCGIFNETMASK, &ifReq ) < 0){  
  60.                 fprintf(stderr, "Error: %d, cannot get mask\n", errno);  
  61.             }  
  62.             else{  
  63.                 u32_mask = ((struct sockaddr_in *)&ifReq.ifr_addr)->sin_addr.s_addr;  
  64.                 inet_ntop(AF_INET, &u32_mask, maskDotBuf, (socklen_t )sizeof(maskDotBuf));  
  65.                 printf("Mask: %s\n", maskDotBuf);  
  66.             }     
  67.             /*    打印MTU    */  
  68.             bzero(&ifReq,sizeof(struct ifreq));    
  69.             memcpy(ifReq.ifr_name, ifPt->ifr_name, sizeof(ifReq.ifr_name));    
  70.             if (ioctl(sock, SIOCGIFMTU, &ifReq ) < 0){  
  71.                 fprintf(stderr, "Error: %d, cannot get MTU\n", errno);  
  72.             }  
  73.             else{  
  74.                 printf("SIOCGIFMTU:%d\n", ifReq.ifr_mtu);   
  75.             }  
  76.                /*    其他信息的打印方式与掩码和MTU相同    */  
  77.         }  
  78.     }  
  79.       
  80.       
  81.       
  82. }  



运行结果:
[cpp]  view plain copy
  1. windeal@ubuntu:~/Windeal/apue$ ./exe   
  2. Len:320  
  3. Len:64  
  4. IP Address: 127.0.0.1  
  5. Mask: 255.0.0.0  
  6. SIOCGIFMTU:16436  
  7. IP Address: 172.17.92.198  
  8. Mask: 255.255.254.0  
  9. SIOCGIFMTU:1500  
  10. windeal@ubuntu:~/Windeal/apue$   

这篇关于获取网络接口信息——ioctl()函数与结构体struct ifreq、 struct ifconf的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/538325

相关文章

python获取指定名字的程序的文件路径的两种方法

《python获取指定名字的程序的文件路径的两种方法》本文主要介绍了python获取指定名字的程序的文件路径的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 最近在做项目,需要用到给定一个程序名字就可以自动获取到这个程序在Windows系统下的绝对路径,以下

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

Vite 打包目录结构自定义配置小结

《Vite打包目录结构自定义配置小结》在Vite工程开发中,默认打包后的dist目录资源常集中在asset目录下,不利于资源管理,本文基于Rollup配置原理,本文就来介绍一下通过Vite配置自定义... 目录一、实现原理二、具体配置步骤1. 基础配置文件2. 配置说明(1)js 资源分离(2)非 JS 资

SpringBoot 获取请求参数的常用注解及用法

《SpringBoot获取请求参数的常用注解及用法》SpringBoot通过@RequestParam、@PathVariable等注解支持从HTTP请求中获取参数,涵盖查询、路径、请求体、头、C... 目录SpringBoot 提供了多种注解来方便地从 HTTP 请求中获取参数以下是主要的注解及其用法:1

GO语言中函数命名返回值的使用

《GO语言中函数命名返回值的使用》在Go语言中,函数可以为其返回值指定名称,这被称为命名返回值或命名返回参数,这种特性可以使代码更清晰,特别是在返回多个值时,感兴趣的可以了解一下... 目录基本语法函数命名返回特点代码示例命名特点基本语法func functionName(parameters) (nam

Python Counter 函数使用案例

《PythonCounter函数使用案例》Counter是collections模块中的一个类,专门用于对可迭代对象中的元素进行计数,接下来通过本文给大家介绍PythonCounter函数使用案例... 目录一、Counter函数概述二、基本使用案例(一)列表元素计数(二)字符串字符计数(三)元组计数三、C

Python中的filter() 函数的工作原理及应用技巧

《Python中的filter()函数的工作原理及应用技巧》Python的filter()函数用于筛选序列元素,返回迭代器,适合函数式编程,相比列表推导式,内存更优,尤其适用于大数据集,结合lamb... 目录前言一、基本概念基本语法二、使用方式1. 使用 lambda 函数2. 使用普通函数3. 使用 N

MySQL中REPLACE函数与语句举例详解

《MySQL中REPLACE函数与语句举例详解》在MySQL中REPLACE函数是一个用于处理字符串的强大工具,它的主要功能是替换字符串中的某些子字符串,:本文主要介绍MySQL中REPLACE函... 目录一、REPLACE()函数语法:参数说明:功能说明:示例:二、REPLACE INTO语句语法:参数

Java集合中的链表与结构详解

《Java集合中的链表与结构详解》链表是一种物理存储结构上非连续的存储结构,数据元素的逻辑顺序的通过链表中的引用链接次序实现,文章对比ArrayList与LinkedList的结构差异,详细讲解了链表... 目录一、链表概念与结构二、当向单链表的实现2.1 准备工作2.2 初始化链表2.3 打印数据、链表长

python中update()函数的用法和一些例子

《python中update()函数的用法和一些例子》update()方法是字典对象的方法,用于将一个字典中的键值对更新到另一个字典中,:本文主要介绍python中update()函数的用法和一些... 目录前言用法注意事项示例示例 1: 使用另一个字典来更新示例 2: 使用可迭代对象来更新示例 3: 使用