struct ifreq学习和实例

一、struct ifreq结构体

这个结构定义在/usr/include/net/if.h,用来配置和获取ip地址,掩码,MTU等接口信息的。

[cpp] view plain copy

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

二、用法:

通过ioctl()函数调用
下表列出了网络相关ioctl请求的request 参数以及arg 地址必须指向的数据类型:

  

类别 Request 说明 数据类型


SIOCATMARK 
SIOCSPGRP 
SIOCGPGRP
是否位于带外标记 
设置套接口的进程ID 或进程组ID 
获取套接口的进程ID 或进程组ID
int 
int 
int

FIONBIN 
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
I_xxx

实例一,获取网卡的IP地址:

[cpp] view plain copy

  1. #include <string.h>
  2. #include <sys/socket.h>
  3. #include <sys/ioctl.h>
  4. #include <net/if.h>
  5. #include <stdio.h>
  6. #include <netinet/in.h>
  7. #include <arpa/inet.h>
  8. int main()
  9. {
  10. int inet_sock;
  11. struct ifreq ifr;
  12. inet_sock = socket(AF_INET, SOCK_DGRAM, 0);
  13. strcpy(ifr.ifr_name, "eth0");
  14. //SIOCGIFADDR标志代表获取接口地址
  15. if (ioctl(inet_sock, SIOCGIFADDR, &ifr) <  0)
  16. perror("ioctl");
  17. printf("%s\n", inet_ntoa(((struct sockaddr_in*)&(ifr.ifr_addr))->sin_addr));
  18. return 0;
  19. }

实例二,实现简单ifconfig功能:

[cpp] view plain copy

  1. /**
  2. * \file getifstat.c
  3. * \author  wzj
  4. * \brief 访问这个struct ifconf 修改,查询状态
  5. * \version
  6. * \note
  7. * \date: 2012年08月11日星期六22:55:25
  8. */
  9. #include <net/if.h>       /* for ifconf */
  10. #include <linux/sockios.h>    /* for net status mask */
  11. #include <netinet/in.h>       /* for sockaddr_in */
  12. #include <sys/socket.h>
  13. #include <sys/types.h>
  14. #include <sys/ioctl.h>
  15. #include <stdio.h>
  16. #define MAX_INTERFACE   (16)
  17. void port_status(unsigned int flags);
  18. /* set == 0: do clean , set == 1: do set! */
  19. int set_if_flags(char *pif_name, int sock, int status, int set)
  20. {
  21. struct ifreq ifr;
  22. int ret = 0;
  23. strncpy(ifr.ifr_name, pif_name, strlen(pif_name) + 1);
  24. ret = ioctl(sock, SIOCGIFFLAGS, &ifr);
  25. if(ret)
  26. return -1;
  27. /* set or clean */
  28. if(set)
  29. ifr.ifr_flags |= status;
  30. else
  31. ifr.ifr_flags &= ~status;
  32. /* set flags */
  33. ret = ioctl(sock, SIOCSIFFLAGS, &ifr);
  34. if(ret)
  35. return -1;
  36. return 0;
  37. }
  38. int get_if_info(int fd)
  39. {
  40. struct ifreq buf[MAX_INTERFACE];
  41. struct ifconf ifc;
  42. int ret = 0;
  43. int if_num = 0;
  44. ifc.ifc_len = sizeof(buf);
  45. ifc.ifc_buf = (caddr_t) buf;
  46. ret = ioctl(fd, SIOCGIFCONF, (char*)&ifc);
  47. if(ret)
  48. {
  49. printf("get if config info failed");
  50. return -1;
  51. }
  52. /* 网口总数 ifc.ifc_len 应该是一个出入参数 */
  53. if_num = ifc.ifc_len/sizeof(struct ifreq);
  54. printf("interface num is interface = %d\n", if_num);
  55. while(if_num-- > 0)
  56. {
  57. printf("net device: %s\n", buf[if_num].ifr_name);
  58. /* 获取第n个网口信息 */
  59. ret = ioctl(fd, SIOCGIFFLAGS, (char*)&buf[if_num]);
  60. if(ret)
  61. continue;
  62. /* 获取网口状态 */
  63. port_status(buf[if_num].ifr_flags);
  64. /* 获取当前网卡的ip地址 */
  65. ret = ioctl(fd, SIOCGIFADDR, (char*)&buf[if_num]);
  66. if(ret)
  67. continue;
  68. printf("IP address is: \n%s\n", inet_ntoa(((struct sockaddr_in *)(&buf[if_num].ifr_addr))->sin_addr));
  69. /* 获取当前网卡的mac */
  70. ret = ioctl(fd, SIOCGIFHWADDR, (char*)&buf[if_num]);
  71. if(ret)
  72. continue;
  73. printf("%02x:%02x:%02x:%02x:%02x:%02x\n\n",
  74. (unsigned char)buf[if_num].ifr_hwaddr.sa_data[0],
  75. (unsigned char)buf[if_num].ifr_hwaddr.sa_data[1],
  76. (unsigned char)buf[if_num].ifr_hwaddr.sa_data[2],
  77. (unsigned char)buf[if_num].ifr_hwaddr.sa_data[3],
  78. (unsigned char)buf[if_num].ifr_hwaddr.sa_data[4],
  79. (unsigned char)buf[if_num].ifr_hwaddr.sa_data[5]
  80. );
  81. }
  82. }
  83. void port_status(unsigned int flags)
  84. {
  85. if(flags & IFF_UP)
  86. {
  87. printf("is up\n");
  88. }
  89. if(flags & IFF_BROADCAST)
  90. {
  91. printf("is broadcast\n");
  92. }
  93. if(flags & IFF_LOOPBACK)
  94. {
  95. printf("is loop back\n");
  96. }
  97. if(flags & IFF_POINTOPOINT)
  98. {
  99. printf("is point to point\n");
  100. }
  101. if(flags & IFF_RUNNING)
  102. {
  103. printf("is running\n");
  104. }
  105. if(flags & IFF_PROMISC)
  106. {
  107. printf("is promisc\n");
  108. }
  109. }
  110. int main()
  111. {
  112. int fd;
  113. fd = socket(AF_INET, SOCK_DGRAM, 0);
  114. if(fd > 0)
  115. {
  116. get_if_info(fd);
  117. close(fd);
  118. }
  119. return 0;
  120. }

运行结果:

interface num is interface = 2
net device: eth0
is up
is broadcast
is running
IP address is: 
192.168.100.200
54:be:f7:33:57:26

net device: lo
is up
is loop back
is running
IP address is: 
127.0.0.1
00:00:00:00:00:00

原文地址:https://www.cnblogs.com/zhengAloha/p/8371177.html

时间: 2024-10-10 04:29:05

struct ifreq学习和实例的相关文章

struct ifreq结构体与ip,子网掩码,网关等信息

总结一下,今天学习的关于通过socket,ioctl来获得ip,netmask等信息,其中很多内容参照了很多网上的信息,我会一一列出的 我用的这个函数,就是下面这个函数,其中的有一些全局变量,很好懂,也就不多做解释了一.下面对这个函数进行注解一下: int get_nic_IP_Address()//获取各网卡IP地址.子网掩码{ struct ifreq ifreq;  //声明一个struct ifreq结构体(这个结构体中有很多重要的参数,具体可以参照第二的补充)   int sock; 

SQL语句学习手册实例版

SQL语句学习手册实例版 表操作 例1  对于表的教学管理数据库中的表 STUDENTS ,可以定义如下: CREATE  TABLE  STUDENTS (SNO      NUMERIC (6, 0) NOT NULL SNAME    CHAR (8) NOT NULL AGE      NUMERIC(3,0) SEX      CHAR(2) BPLACE  CHAR(20) PRIMARY KEY(SNO)) 例2  对于表的教学管理数据库中的表 ENROLLS ,可以定义如下: C

菜鸟学习javascript实例教程

菜鸟学习javascript实例教程 1.用JS显示文字的例子: <html><body> <script type="text/javascript">document.write("Hello World!")</script> </body></html> 2.用HTML标签来格式化文本的例子: <html><body> <script type="

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

转载请注明出处:windeal专栏 Linux 下 可以使用ioctl()函数 以及 结构体 struct ifreq  结构体struct ifconf来获取网络接口的各种信息. ioctl 首先看ioctl()用法 ioctl()原型如下: #include <sys/ioctl.h> int ioctl(int fd, int request, ...); 参数: fd     : 文件描述符 request:  表示要请求的信息.如IP地址.网络掩码等 ...     :  后面的可变

SQLite学习手册(实例代码&lt;一&gt;)

一.获取表的Schema信息:       1). 动态创建表.     2). 根据sqlite3提供的API,获取表字段的信息,如字段数量以及每个字段的类型.     3). 删除该表.     见以下代码及关键性注释:  1 #include <sqlite3.h>  2 #include <string>  3  4 using namespace std;  5  6 void doTest()  7 {  8     sqlite3* conn = NULL;  9  

net -t struct ifreq

结构原型: struct ifreq { #define IFHWADDRLEN 6 union { char ifrn_name[IFNAMSIZ]; } ifr_ifrn; union { struct sockaddr ifru_addr; struct sockaddr ifru_dstaddr; struct sockaddr ifru_broadaddr; struct sockaddr ifru_netmask; struct sockaddr ifru_hwaddr; short

vue2.0学习(四)-实例和内置组件

vue2.0学习(四)-实例和内置组件 1.实例入门-实例属性 一.Vue和Jquery.js一起使用 下载可以去官网进行下载,我这里使用的版本是3.1.1,下载好后在需要的页面引入就可以了.当然你还有很多其它的方法引入jquery,只要可以顺利引入就可以了. <script type="text/javascript" src="../assets/js/jquery-3.1.1.min.js"></script> <!DOCTYPE

linux下网络编程学习——入门实例ZZ

http://www.cppblog.com/cuijixin/archive/2008/03/14/44480.html 是不是还对用c怎么实现网络编程感到神秘莫测阿,我们这里就要撕开它神秘的面纱,呵呵. 一起来: 诶,不要着急,我们先来介绍一些网络程序的主要执行过程,主要是便于大家更好的理解下面的程序实例哦 : 1)系统启动服务器执行.服务器完成一些初始化操作,然后进入睡眠状态,等待客户机请求.2)在网络的某台机器上,用户执行客户机程序3)客户机进行与服务器进程建立一条连接4)连接建立后,客

设计模式学习-及实例源码和电子书下载

从本篇博文讲述23中设计模式,对每种设计模式给出实例代码.本篇博文最后都会给出代码下载地址. 本博文的参考书是<设计模式之禅>和<大话设计模式>这两本书. 但是<大话设计模式>一书并不是使用java语言编写的,所以对于初级Java或者有一定java基础的人看起来并不直观,特别是对于没有设计模式概念的同学看起来有点费劲,还有一个不好的地方是里面的每种模式的讲述都是基于一定的情景下讲述的,还有大鸟和菜鸟冗余的对话,看起来真是冗余!!(注:这是个人的理解和感受!大家不喜的话勿