转载请注明出处: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. 漂亮的输出-----prettytable和colorama的使用

    Python通过prettytable模块将输出内容如表格方式整齐输出,python本身并不内置,需要独立安装该第三方库. 1 pip install PrettyTable 1 #源码安装 2 wg ...

  2. Java Calendar类总结

    在实际项目当中,我们经常会涉及到对时间的处理,例如登陆网站,我们会看到网站首页显示XXX,欢迎您!今天是XXXX年....某些网站会记录下用户登陆的时间,比如银行的一些网站,对于这些经常需要处理的问题 ...

  3. [转]手把手教你搭建Hive Web环境

    了解Hive的都知道Hive有三种使用方式——CLI命令行,HWI(hie web interface)浏览器 以及 Thrift客户端连接方式. 为了体验下HWI模式,特意查询了多方的资料,都没有一 ...

  4. 一.复习GCC编译器的用法

    1.复习GCC编译器的用法 欲善其工,那么要先利其器.在这个C语言巩固与提高的阶段中,如果想要更好的达成预期目标,首先就要熟练掌握GCC编译器的用法.以下是GCC相关知识: GCC使用语法 gcc 选 ...

  5. 百度云如何免费扩容至2055G?

    百度云如何免费扩容至2055G? 上篇说到整一个新的百度账号,那么5G的百度云内存肯定满足不了我们收集癖的需求.那么就来了解一下怎么扩容吧. 主要是在手机端实现的 用这个新的百度账号在手机APP上登录 ...

  6. LaTeX模板 - FORMCM

    LaTex 模板 - FORMCM \documentclass{mcmthesis} \mcmsetup{CTeX = true, % 使用 CTeX 套装时,设置为 true tcn = 8989 ...

  7. 03_Storm编程上手-wordcount

    1. Storm编程模型概要 消息源spout, 继承BaseRichSpout类 或 实现IRichSpout接口1)BaseRichSpout类相对比较简单,需要覆写的方法较少,满足基本业务需求2 ...

  8. JavaScript高级程序设计-读书笔记(3)

    第8章 BOM 1.window对象 (1)全局作用域 BOM的核心对象是window,它表示浏览器的一个实例.在浏览器中,window对象既是通过JavaScript访问浏览器窗口的一个接口,又是E ...

  9. Object.assign() 从一个或多个源对象复制到目标对象

    Object.assign()方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象.它将返回目标对象. 1.语法: Object.assign(target, ... , sources) 参 ...

  10. JavaScript声明全局变量三种方式的异同

    JavaScript中声明变量很简单var(关键字)+变量名(标识符). 方式1 1 2 var test; var test = 5; 需注意的是该句不能包含在function内,否则是局部变量.这 ...