概述
ioctl函数传统上一直作为那些不适合归入其他精细定义类别的特性的系统接口。例如,Unix终端接口传统上使用ioctl访问,然后POSIX为终端创造了12个新函数:tcgetattr:获取终端属性;tcflush:冲刷待处理输入或输出。
网络程序(特别是服务器程序)经常在程序启动执行后使用ioctl获取所在主机全部网络接口的信息,包括:接口地址、是否支持广播、是否支持多播等等。
-
ioctl函数
#include <unistd.h>
int ioctl(int fd, int request, ... /* void *arg */);
//返回:若成功则为0,若出错则为-1
其中第三个参数总是一个指针,但指针的类型依赖于request参数。
我们可以把和网络相关的请求(request)划分为6类:
- 套接字套作
- 文件操作
- 接口操作
- ARP高速缓存操作
- 路由表操作
- 流系统
以下是网络相关ioctl请求的request参数以及arg地址必须指向的数据类型:
-
套接字操作
明确用于套接字的ioctl请求有3个。它们都要求ioctl的第三个参数是指向某个整数的一个指针。
- SIOCATMARK:如果本套接字的读指针当前位于带外标记,那就通过由第三个参数指向的整数返回一个非0值;否则返回一 个0值;
- SIOCGPGRP:通过由第三个参数指向的整数返回本套接字的进程ID或进程组ID,该ID指定针对本套接字的SIGIO或SIGURG信号的接收进程。本请求和fcntl的F_GETOWN命令等效;
- SIOCSPGRP:把本套接字的进程ID或进程组ID设置成由第三个参数指向的整数,该ID指定针对本套接字的SIGIO或SIGURG信号的接收进程。本请求和fcntl的F_SETOWN命令等效;
-
文件操作
以下5个请求都要求ioctl的第三个参数指向一个整数:
- FIONBIO:根据ioctl的第三个参数指向一个0值或非0值,可清除或设置本套接字的非阻塞式I/O标志。本请求和O_NONBLOCK文件状态标志等效,而可以通过fcntl的F_SETFL命令清除或设置该标志;
- FIOASYNC:根据ioctl的第三个参数指向一个0值或非0值,可清除或设置针对本套接字的信号驱动异步I/O标志,它决定是否收取针对本套接字的异步I/O信号(SIGIO)。本请求和O_ASYNC文件状态标志等效,而可以通过fcntl的F_SETFL命令清除或设置该标志;
- FIONREAD:通过由ioctl的第三个参数指向的整数返回当前在本套接字接收缓冲区中的字节数;
- FIOSETOWN:对于套接字和SIOCSPGRP等效;
- FIOGETOWN:对于套接字和SIOCGPFRP等效;
-
ARP高速缓存操作
ARP高速缓存也通过ioctl函数曹忠。这些请求使用arpreq结构,它定义在头文件<net/if_arp.h>中:
strcut arpreq{
struct sockaddr arp_pa;
struct sockaddr arp_ha;
int arp_flags;
};
#define ATF_INUSE 0x01
#define ATF_COM 0X02
#define ATF_PERM 0x04
#define ATF_PUBL 0x08
ioctl的第三个参数必须指向某个arpreq结构。操纵ARP高速缓存的ioctl请求有3个:
- SIOCSARP:把一个新的表项加到ARP高速缓存,或者修改其中已经存在的一个表项。其中arp_pa是一个含有IP地址的网际网套接字地址结构,arp_ha则是一个通用套接字地址结构,它的sa_family值为AF_UNSPEC,sa_data中含有硬件地址。ATF_PERM和ATF_PUBL这两个标志也可以由应用程序制定。另两个则由内核设置;
- SIOCDARP:从ARP高速缓存中删除一个表项。调用者指定要删除表项的网际网地址;
- SIOCGARP:从ARP高速缓存中获取一个表项。调用者指定网际网地址,相应的硬件地址(例如以太网地址)随标志一起返回;