zl程序教程

您现在的位置是:首页 >  其它

当前栏目

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

获取 信息 自己 路由器 动手 ioctl 网络接口
2023-09-27 14:29:31 时间

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

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

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

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


接下来,就开始利用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;

10 int sockfd;

11 if(-1 == socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ALL))) 

13 perror("socket build !");

14 return 1;

15 } 

16 if(-1 == ioctl(sockfd,SIOCGIFCONF,(char *) ifc))//SIOCGIFCONF用来获取所有配置接口的信息,将所获取的信息保存到ifc里。

18 perror("SIOCGIFCONF !");

19 return 1;

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 tmp--)

27 printf("the interface name is %s\n",buf[tmp].ifr_name);

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 } 

38 /* IP地址的获取 */

39 if(0 == ioctl(sockfd,SIOCGIFADDR,(char *) buf[tmp]))

41 tmpbuf = (char *)inet_ntoa(((struct sockaddr_in*) ( buf[tmp].ifr_addr))- sin_addr);

42 printf("IPAdress :%s \n",tmpbuf);

43 } 

45 /* 子网掩码的获取 */

46 if(0 == ioctl(sockfd,SIOCGIFNETMASK,(char *) buf[tmp])) 

48 tmpbuf = (char *)inet_ntoa(((struct sockaddr_in*) ( buf[tmp].ifr_addr))- sin_addr);

49 printf("netmask:%s \n",tmpbuf);

50 } 

52 /* 广播地址的获取 */

53 if(0 == ioctl(sockfd,SIOCGIFBRDADDR,(char *) buf[tmp]))

55 tmpbuf = (char *)inet_ntoa(((struct sockaddr_in*)( buf[tmp].ifr_addr))- sin_addr);

56 printf("broadcast address:%s \n",tmpbuf);

57 } 

59 /* MAC地址的获取 */

60 if(0 == ioctl(sockfd,SIOCGIFHWADDR,(char *) buf[tmp]))

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 } 

71 }
复制代码

 

 

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

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

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

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


第四章TCP/IP网络层设备路由器 路由是指路由器从一个接口上收到数据包,根据数据包的目的地址进行定向并转发到另一个 接口的过程,路由通常与桥接来对比,路由工作包含两个基本的动作,一是确定最佳路径, 二是通过网络传输信息,路由分为静态路由和动态路由和直连路由三种来源
Linux网络管理之网卡、网络接口开关设置 ifup命令用于激活指定的网络接口。ifup命令会去读取/etc/sysconfig/network-scripts/目录下的相关网络接口的配置文件,并根据配置文件的内容来激活该网络接口。
Linux网络管理之arp命令 – 操纵系统arp缓存(地址解析协议) arp命令的英文全拼“Address Resolution Protocol” 。该命令用于操作主机的arp缓存,它可以显示arp缓存中的所有条目、删除指定的条目或者添加静态的ip地址与MAC地址对应关系。
Linux网络管理之ifconfig命令 – 显示或设置网络设备 ifconfig命令的英文全称是“network interfaces configuring”,即用于配置和显示Linux内核中网络接口的网络参数。用ifconfig命令配置的网卡信息,在网卡重启后机器重启后,配置就不存在。要想将上述的配置信息永远的存的电脑里,那就要修改网卡的配置文件了。