获取网络接口信息——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如何实现PDF隐私信息检测

《Python如何实现PDF隐私信息检测》随着越来越多的个人信息以电子形式存储和传输,确保这些信息的安全至关重要,本文将介绍如何使用Python检测PDF文件中的隐私信息,需要的可以参考下... 目录项目背景技术栈代码解析功能说明运行结php果在当今,数据隐私保护变得尤为重要。随着越来越多的个人信息以电子形

Python中顺序结构和循环结构示例代码

《Python中顺序结构和循环结构示例代码》:本文主要介绍Python中的条件语句和循环语句,条件语句用于根据条件执行不同的代码块,循环语句用于重复执行一段代码,文章还详细说明了range函数的使... 目录一、条件语句(1)条件语句的定义(2)条件语句的语法(a)单分支 if(b)双分支 if-else(

Python itertools中accumulate函数用法及使用运用详细讲解

《Pythonitertools中accumulate函数用法及使用运用详细讲解》:本文主要介绍Python的itertools库中的accumulate函数,该函数可以计算累积和或通过指定函数... 目录1.1前言:1.2定义:1.3衍生用法:1.3Leetcode的实际运用:总结 1.1前言:本文将详

如何利用Java获取当天的开始和结束时间

《如何利用Java获取当天的开始和结束时间》:本文主要介绍如何使用Java8的LocalDate和LocalDateTime类获取指定日期的开始和结束时间,展示了如何通过这些类进行日期和时间的处... 目录前言1. Java日期时间API概述2. 获取当天的开始和结束时间代码解析运行结果3. 总结前言在J

使用Navicat工具比对两个数据库所有表结构的差异案例详解

《使用Navicat工具比对两个数据库所有表结构的差异案例详解》:本文主要介绍如何使用Navicat工具对比两个数据库test_old和test_new,并生成相应的DDLSQL语句,以便将te... 目录概要案例一、如图两个数据库test_old和test_new进行比较:二、开始比较总结概要公司存在多

轻松上手MYSQL之JSON函数实现高效数据查询与操作

《轻松上手MYSQL之JSON函数实现高效数据查询与操作》:本文主要介绍轻松上手MYSQL之JSON函数实现高效数据查询与操作的相关资料,MySQL提供了多个JSON函数,用于处理和查询JSON数... 目录一、jsON_EXTRACT 提取指定数据二、JSON_UNQUOTE 取消双引号三、JSON_KE

MySQL数据库函数之JSON_EXTRACT示例代码

《MySQL数据库函数之JSON_EXTRACT示例代码》:本文主要介绍MySQL数据库函数之JSON_EXTRACT的相关资料,JSON_EXTRACT()函数用于从JSON文档中提取值,支持对... 目录前言基本语法路径表达式示例示例 1: 提取简单值示例 2: 提取嵌套值示例 3: 提取数组中的值注意

java获取图片的大小、宽度、高度方式

《java获取图片的大小、宽度、高度方式》文章介绍了如何将File对象转换为MultipartFile对象的过程,并分享了个人经验,希望能为读者提供参考... 目China编程录Java获取图片的大小、宽度、高度File对象(该对象里面是图片)MultipartFile对象(该对象里面是图片)总结java获取图片

Java通过反射获取方法参数名的方式小结

《Java通过反射获取方法参数名的方式小结》这篇文章主要为大家详细介绍了Java如何通过反射获取方法参数名的方式,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1、前言2、解决方式方式2.1: 添加编译参数配置 -parameters方式2.2: 使用Spring的内部工具类 -

Java如何获取视频文件的视频时长

《Java如何获取视频文件的视频时长》文章介绍了如何使用Java获取视频文件的视频时长,包括导入maven依赖和代码案例,同时,也讨论了在运行过程中遇到的SLF4J加载问题,并给出了解决方案... 目录Java获取视频文件的视频时长1、导入maven依赖2、代码案例3、SLF4J: Failed to lo