转载请注明出处:windeal专栏

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


ioctl

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

比如我们请求所有网络接口的清单:
struct ifconf IoCtlReq;
...
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用来保存某个接口的信息。
// if.h
/*
* Interface request structure used for socket
* ioctl's. All interface ioctl's must have parameter
* definitions which begin with ifr_name. The
* remainder may be interface specific.
*/
struct ifreq {
#define IFHWADDRLEN 6
union
{
char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */
} ifr_ifrn; union {
struct sockaddr ifru_addr;
struct sockaddr ifru_dstaddr;
struct sockaddr ifru_broadaddr;
struct sockaddr ifru_netmask;
struct sockaddr ifru_hwaddr;
short ifru_flags;
int ifru_ivalue;
int ifru_mtu;
struct ifmap ifru_map;
char ifru_slave[IFNAMSIZ]; /* Just fits the size */
char ifru_newname[IFNAMSIZ];
void __user * ifru_data;
struct if_settings ifru_settings;
} ifr_ifru;
};
#define ifr_name ifr_ifrn.ifrn_name /* interface name */
#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */
#define ifr_addr ifr_ifru.ifru_addr /* address */
#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-p lnk */
#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
#define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */
#define ifr_flags ifr_ifru.ifru_flags /* flags */
#define ifr_metric ifr_ifru.ifru_ivalue /* metric */
#define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
#define ifr_map ifr_ifru.ifru_map /* device map */
#define ifr_slave ifr_ifru.ifru_slave /* slave device */
#define ifr_data ifr_ifru.ifru_data /* for use by interface */
#define ifr_ifindex ifr_ifru.ifru_ivalue /* interface index */
#define ifr_bandwidth ifr_ifru.ifru_ivalue /* link bandwidth */
#define ifr_qlen ifr_ifru.ifru_ivalue /* Queue length */
#define ifr_newname ifr_ifru.ifru_newname /* New name */
#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通常用来保存所有接口信息
// if.h
/*
* Structure used in SIOCGIFCONF request.
* Used to retrieve interface configuration
* for machine (useful for programs which
* must know all networks accessible).
*/
struct ifconf {
int ifc_len; /* size of buffer */
union {
char __user *ifcu_buf;
struct ifreq __user *ifcu_req;
} ifc_ifcu;
};
#define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */
#define ifc_req ifc_ifcu.ifcu_req /* array of structures */

该结构体可以用来获取所哟网络接口的名字和信息(不是全部信息,是ip地址)



Example:

#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <string.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
typedef uint32_t uint32;
#define MAX_IF 10
int
main()
{
struct ifreq ifVec[MAX_IF];//用来保存所有接口 int sock = -1;
if ( (sock = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 )
fprintf(stderr, "Error:%d, cannot open RAM;\n"); // get if vector
struct ifconf ioIfConf;
ioIfConf.ifc_buf = (void *)ifVec;
ioIfConf.ifc_len = sizeof(ifVec);
printf("Len:%d\n", ioIfConf.ifc_len); if (ioctl(sock, SIOCGIFCONF, &ioIfConf) < 0 )//获取所有网络接口信息
fprintf(stderr, "Error:%d ioctl IFCONF\n"); printf("Len:%d\n", ioIfConf.ifc_len);// 和前面到len对比,发现ioctl修改里len到大小
//循环打印每个网络接口到信息
{
struct ifreq *ifPt;
struct ifreq *ifEndPt;
ifPt = ifVec;
ifEndPt = (void *)((char *)ifVec + ioIfConf.ifc_len);
for (ifPt = ifVec; ifPt < ifEndPt; ifPt++)
{
struct ifreq ifReq;
if ( ifPt->ifr_addr.sa_family != AF_INET ) {
continue;
} // Temp keepers of interface params...
uint32 u32_addr, u32_mask; /* 打印ip地址 */
char ipDotBuf[16], subnetDotBuf[16], maskDotBuf[16]; // 保存点分十进制到ip地址
u32_addr = ((struct sockaddr_in *)&ifPt->ifr_addr)->sin_addr.s_addr;
inet_ntop(AF_INET, &u32_addr, ipDotBuf, (socklen_t )sizeof(ipDotBuf));
printf("IP Address: %s\n", ipDotBuf); /* 打印地址掩码 */
bzero(&ifReq,sizeof(struct ifreq));
memcpy(ifReq.ifr_name, ifPt->ifr_name, sizeof(ifReq.ifr_name));
if (ioctl(sock, SIOCGIFNETMASK, &ifReq ) < 0){
fprintf(stderr, "Error: %d, cannot get mask\n", errno);
}
else{
u32_mask = ((struct sockaddr_in *)&ifReq.ifr_addr)->sin_addr.s_addr;
inet_ntop(AF_INET, &u32_mask, maskDotBuf, (socklen_t )sizeof(maskDotBuf));
printf("Mask: %s\n", maskDotBuf);
}
/* 打印MTU */
bzero(&ifReq,sizeof(struct ifreq));
memcpy(ifReq.ifr_name, ifPt->ifr_name, sizeof(ifReq.ifr_name));
if (ioctl(sock, SIOCGIFMTU, &ifReq ) < 0){
fprintf(stderr, "Error: %d, cannot get MTU\n", errno);
}
else{
printf("SIOCGIFMTU:%d\n", ifReq.ifr_mtu);
}
/* 其他信息的打印方式与掩码和MTU相同 */
}
} }


运行结果:
windeal@ubuntu:~/Windeal/apue$ ./exe
Len:320
Len:64
IP Address: 127.0.0.1
Mask: 255.0.0.0
SIOCGIFMTU:16436
IP Address: 172.17.92.198
Mask: 255.255.254.0
SIOCGIFMTU:1500
windeal@ubuntu:~/Windeal/apue$


















获取网络接口信息——ioctl()函数与结构体struct ifreq、 struct ifconf的更多相关文章

  1. 自己动手写路由器之ioctl获取网络接口信息

    最近打算写一个简单路由器,里面有用到ioctl获取网络接口信息,那就先把这部分单独拿出来说一说吧! ioctl这个函数,可以用来对特殊文件的基础设备参数进行操作,它们可以完成与打开文件描述符相关联的控 ...

  2. Linux获取网络接口信息

    linux获取网络接口信息需要用到的函数为ioctl(),结构体struct ifreq,struct ifconf 1.ioctl()函数原型及作用 #include <sys/ioctl.h ...

  3. C语言笔记 08_函数指针&回调函数&字符串&结构体&位域

    函数指针 函数指针是指向函数的指针变量. 通常我们说的指针变量是指向一个整型.字符型或数组等变量,而函数指针是指向函数. 函数指针可以像一般函数一样,用于调用函数.传递参数. 函数指针变量的声明: / ...

  4. Go基础3:函数、结构体、方法、接口

    目录 1. 函数 1.1 函数返回值 同一种类型返回值 带变量名的返回值 函数中的参数传递 函数变量 1.2 匿名函数--没有函数名字的函数 在定义时调用匿名函数 将匿名函数赋值给变量 匿名函数用作回 ...

  5. 【AT91SAM3S】SAM3S-EK Demo工程中,LCD驱动程序的加载(函数指针结构体)

    为了调试LCD,在英倍特的板子上烧Atmel的sam3s-ek_demo_1.4_source示例代码.LCD显示正常了,却找不到LCD的驱动究竟在哪. 花了好久,追踪到了这个执行过程. 进入main ...

  6. go 学习 (三):函数 & 指针 & 结构体

    一.函数 函数声明 // 声明语法 func funcName (paramName paramType, ...) (returnType, returnType...) { // do somet ...

  7. struct--------构造函数对结构体初始化的影响

    struct--------构造函数对结构体初始化的影响. 没有构造函数时使用如下: struct ClassBook{  int number;  int age; }; int main() { ...

  8. 【Unity Shader】---常用帮助函数、结构体和全局变量

    [Unity Shader]---常用帮助函数.结构体和全局变量 一.内置包含文件 Unity中有类似于C++的包含文件.cginc,在编写Shader时我们可以使用#include指令把这些文件包含 ...

  9. <algorithm>里的sort函数对结构体排序

    题目描述 每天第一个到机房的人要把门打开,最后一个离开的人要把门关好.现有一堆杂乱的机房签到.签离记录,请根据记录找出当天开门和关门的人. 输入描述: 每天的记录在第一行给出记录的条目数M (M &g ...

随机推荐

  1. git失败案例

    哈哈哈,git终于能push了,哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈 我怀疑是系统版本的问题,之前一直不没能pu ...

  2. 利用MacBook Air入侵无线网络

    目前无线网络的加密方式主要有WEP,WPA/WPA2.这是最常看到的加密方式,最近由于需要,专门去研究了一下如何入侵无线网络. 1.入侵WEP加密的无线网络 WEP加密方式现在已经很不安全了,因为只要 ...

  3. Restful Api CRUD 标准示例 (Swagger2+validator)

    为什么要写这篇贴? 要写一个最简单的CRUD 符合 Restful Api    规范的  一个Controller, 想百度搜索一下 直接复制拷贝 简单修改一下 方法内代码. 然而, 搜索结果让我无 ...

  4. swagger2 坑 记录

    swagger2 只认 @RequestMapping 注解! 不认@RestController 注解 @RestController @RequestMapping(value = "/ ...

  5. SQL优化- in和not in

    in不会导致索引失效,但最终数据库会将in语句解析为or语句,eg: select * from T_MAIN_PROCESS t where t.audit_status_code in ('05' ...

  6. Python基础笔记系列八:字符串的运算和相关函数

    本系列教程供个人学习笔记使用,如果您要浏览可能需要其它编程语言基础(如C语言),why?因为我写得烂啊,只有我自己看得懂!! 字符串的运算1.字符串的加法和乘法 python中不但支持字符串相加,还支 ...

  7. 仿照Chome的GhostPage调试功能

    今天在测试过程中发现了网站的一个bug,在大屏幕上是自适应的,小屏幕笔记本上高度不是自适应,html的高度并不是浏览器的高度,小屏幕总是差了一截,在调试过程中偶然发现差的那一小截正好是一个横向滑动条的 ...

  8. 关于Spring中applicationContext.xml配置错误“org/springframework/transaction/interceptor/TransactionInterceptor”的问题解决

    问题描述: 在配置spring的applicationContext.xml中的默认事务管理器的时候可能会出现这样的错误: Error occured processing XML 'org/spri ...

  9. maven笔记(2)

    项目管理利器(Maven)——maven的生命周期和插件Maven的生命周期大概如下:clean compile test package install这几个命令对应了一个项目的完整的构建过程,这几 ...

  10. (转)SQL Server中的索引结构与疑惑

    说实话我从没有在实际项目中使用过索引,仅知道索引是一个相当重要的技术点,因此我也看了不少文章知道了索引的区别.分类.优缺点以及如何使用索引.但关于索引它最本质的是什么笔者一直没明白,本文是笔者带着这些 ...