最近打算写一个简单路由器,里面有用到ioctl获取网络接口信息,那就先把这部分单独拿出来说一说吧!

ioctl这个函数,可以用来对特殊文件的基础设备参数进行操作,它们可以完成与打开文件描述符相关联的控制功能。在程序启动时获得主机上所有接口的信息: 接口的地址、接口是否支持广播、是否支持多播等等。成功返回0,出错则返回-1。

本文里只是单独对获取网络接口信息部分讲解。

先列出一些本文里ioctl的相关ioctl 请求的request 参数以及arg 地址必须指向的数据类型:

request参数  相关说明 指向数据类型
SIOCGIFCONF 获取所有接口信息 struct ifconf
SIOCGIFADDR 获取接口地址 struct ifreq
SIOCGIFFLAGS 获取接口状态 struct ifreq
SIOCGIFBRDADDR 获取广播地址 struct ifreq
SIOCGIFNETMASK       获取子网掩码 struct ifreq

接下来,就开始利用ioctl以及其参数来获取网络接口的信息了。

直接附上代码,详情请看注释:

 1 int main()
2 {//想要获取当前网口网线插入状态,需要用到ifreq结构体,获取网卡的信息,然后socket结合网卡驱动的ioctl,就可以得到与网线插入状态相关的数据。
3 int number;
4 char *tmpbuf;
5 struct ifconf ifc; //用来保存所有接口信息的
6 struct ifreq buf[16]; //这个结构定义在net/if.h,用来配置ip地址,激活接口,配置MTU等接口信息
7 ifc.ifc_len = sizeof(buf);
8 ifc.ifc_buf = (caddr_t)buf;
9
10 int sockfd;
11 if(-1 == socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ALL)))
12 {
13 perror("socket build !");
14 return 1;
15 }
16 if(-1 == ioctl(sockfd,SIOCGIFCONF,(char *)&ifc))//SIOCGIFCONF用来获取所有配置接口的信息,将所获取的信息保存到ifc里。
17 {
18 perror("SIOCGIFCONF !");
19 return 1;
20 }
21
22 number = ifc.ifc_len / sizeof(struct ifreq);
23 printf("the interface number is %d \n",number);
24 int tmp;
25 for(tmp = number;tmp > 0;tmp--)
26 {
27 printf("the interface name is %s\n",buf[tmp].ifr_name);
28
29 /* 接口的状态信息获取 */
30 if(0 == ioctl(sockfd,SIOCGIFFLAGS,(char *)&buf[tmp]))
31 {
32 if(IFF_UP == buf[tmp].ifr_flags)
33 printf("UP\n");
34 else
35 printf("DOWN");
36 }
37
38 /* IP地址的获取 */
39 if(0 == ioctl(sockfd,SIOCGIFADDR,(char *)&buf[tmp]))
40 {
41 tmpbuf = (char *)inet_ntoa(((struct sockaddr_in*) (&buf[tmp].ifr_addr))->sin_addr);
42 printf("IPAdress :%s \n",tmpbuf);
43 }
44
45 /* 子网掩码的获取 */
46 if(0 == ioctl(sockfd,SIOCGIFNETMASK,(char *)&buf[tmp]))
47 {
48 tmpbuf = (char *)inet_ntoa(((struct sockaddr_in*) (&buf[tmp].ifr_addr))->sin_addr);
49 printf("netmask:%s \n",tmpbuf);
50 }
51
52 /* 广播地址的获取 */
53 if(0 == ioctl(sockfd,SIOCGIFBRDADDR,(char *)&buf[tmp]))
54 {
55 tmpbuf = (char *)inet_ntoa(((struct sockaddr_in*)(&buf[tmp].ifr_addr))->sin_addr);
56 printf("broadcast address:%s \n",tmpbuf);
57 }
58
59 /* MAC地址的获取 */
60 if(0 == ioctl(sockfd,SIOCGIFHWADDR,(char *)&buf[tmp]))
61 {
62 printf("MAC:%02x:%02x:%02x:%02x:%02x:%02x\n\n",
63 (unsigned char) buf[tmp].ifr_hwaddr.sa_data[0],
64 (unsigned char) buf[tmp].ifr_hwaddr.sa_data[1],
65 (unsigned char) buf[tmp].ifr_hwaddr.sa_data[2],
66 (unsigned char) buf[tmp].ifr_hwaddr.sa_data[3],
67 (unsigned char) buf[tmp].ifr_hwaddr.sa_data[4],
68 (unsigned char) buf[tmp].ifr_hwaddr.sa_data[5]);
69 }
70 }
71 }

在驱动程序中实现的ioctl函数体内,实际上是有一个switch{case}结构的,每一个case对应一个命令码,做出一些相应的操作。

下面附上ioctl全参数多对应的命令码的功能的链接:

http://riverzhou2000.blog.163.com/blog/static/105403248201183025729615/

ioctl这个函数还有很多其它的功能,有兴趣的朋友可以问度娘,这里就不加详述了!

自己动手写路由器之ioctl获取网络接口信息的更多相关文章

  1. Linux获取网络接口信息

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

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

    转载请注明出处:windeal专栏 Linux 下 可以使用ioctl()函数 以及 结构体 struct ifreq  结构体struct ifconf来获取网络接口的各种信息. ioctl 首先看 ...

  3. 自己动手写处理器之第四阶段(1)——第一条指令ori的实现

    将陆续上传本人写的新书<自己动手写处理器>(尚未出版),今天是第11篇,我尽量每周四篇 第4章 第一条指令ori的实现 前面几章介绍了非常多预备知识,也描绘了即将要实现的OpenMIPS处 ...

  4. 自己动手写处理器之第一阶段(3)——MIPS32指令集架构简单介绍

    将陆续上传本人写的新书<自己动手写处理器>(尚未出版).今天是第四篇.我尽量每周四篇 1.4 MIPS32指令集架构简单介绍 本书设计的处理器遵循MIPS32 Release 1架构,所以 ...

  5. 自己动手写处理器之第一阶段(2)——MIPS指令集架构的演变

    将陆续上传本人写的新书<自己动手写处理器>(尚未出版),今天是第三篇.我尽量每周四篇 MIPS指令集架构自上世纪80年代出现后.一直在进行着更新换代,从最初的MIPS I到MIPS V,发 ...

  6. 自己动手写处理器之第二阶段(1)——可编程逻辑器件与PLD电路设计流程

    将陆续上传本人写的新书<自己动手写处理器>(尚未出版),今天是第五篇,我尽量每周四篇         通过上一章的介绍,读者应该知道CPU内部有一些主要的电路,比方:译码电路.运算电路.控 ...

  7. 自己动手写处理器之第二阶段(2)——Verilog HDL简单介绍

    将陆续上传本人写的新书<自己动手写处理器>(尚未出版),今天是第六篇.我尽量每周四篇 2.3 Verilog HDL简单介绍 本书实现的OpenMIPS处理器是使用Verilog HDL编 ...

  8. [转]使用GetIfTable获取MIB_IFTABLE和MIB_IFROW获取网络接口信息

    #include <iphlpapi.h> #pragma comment ( lib, "iphlpapi.lib") 使用GetIfTable()获取各个端口信息的 ...

  9. 动手写一个简单的Web框架(Werkzeug路由问题)

    动手写一个简单的Web框架(Werkzeug路由问题) 继承上一篇博客,实现了HelloWorld,但是这并不是一个Web框架,只是自己手写的一个程序,别人是无法通过自己定义路由和返回文本,来使用的, ...

随机推荐

  1. 深入浅出ES6(五):不定参数和默认参数

    作者 Jason Orendorff  github主页  https://github.com/jorendorff 不定参数 我们通常使用可变参函数来构造API,可变参函数可接受任意数量的参数.例 ...

  2. Android开发--使用真机进行USB调试程序

    在android小程序的开发过程中,使用eclipse中的虚拟机进行程序开发速度较慢,用真机开发可以显著提高调试的速度. 这里我用的操作系统是win7专业版,手机型号HM1S: 进行USB调试的主要步 ...

  3. java基础知识回顾之---java String final类普通方法的应用之“模拟字符串Trim方法”

    /* * 4,模拟一个trim功能一致的方法.去除字符串两端的空白  * 思路: * 1,定义两个变量. * 一个变量作为从头开始判断字符串空格的角标.不断++. * 一个变量作为从尾开始判断字符串空 ...

  4. Android 打开闪光灯(手电筒)

    package com.example.openBackLight; import android.app.Activity; import android.hardware.Camera; impo ...

  5. Thread的第一天学习

    1.实现线程的方法: 1)extend Thread 2)implements Runnable 2.下面代码执行哪个run方法: new Thread( new Runnable(){ public ...

  6. [主席树]SPOJ DQUERY

    题目链接 题意:n个数 m个查询 查询的是[l, r]区间内不相同的数的个数 没有修改,因此静态的主席树就好了 将重复的元素建树即可 query的时候加起来,用区间长度(r-l+1)去减就是答案 (q ...

  7. lintcode :Remove Duplicates from Sorted Array II 删除排序数组中的重复数字 II

    题目: 删除排序数组中的重复数字 II 跟进“删除重复数字”: 如果可以允许出现两次重复将如何处理? 样例 给出数组A =[1,1,1,2,2,3],你的函数应该返回长度5,此时A=[1,1,2,2, ...

  8. sed and awk学习笔记

    sed and awk 背景 awk起源追溯至sed和grep,进而追溯至共同的行编辑器ed.实用工具grep来源于ed命令:g/re/p .实用工具awk和sed有一个共同的选项-f用于指定脚本的名 ...

  9. 关于Linux的windows目录的挂载

    今天,linux主机下面要增加一点空间,不想再增加硬盘,所以就在实体机里面就设置了目录共享,添加自己系统的默认账号(为了增加自己主机的安全性,我都是设置的含有标点符号的密码---这也是这次挂载不成功的 ...

  10. python类似微信未读信息图片脚本

    其实就是实现一个效果,给一张图片,然后再右上角给出未读的信息数目,就像我们打开微信的时候,总是看到红点就忍不住想要点击去查看一样. 类似这种效果: 可以知道,图片是给定的,那么只要随机生成一个数字,然 ...