您的位置:首页 > 其它

ioctl函数详细说明

2011-04-20 16:21 330 查看
ioctl
函数

本函数影响由fd
参数引用的一个打开的文件。

#include<unistd.h>

int ioctl( int fd, int request, .../* void *arg */ );

返回0
:成功 -1
:出错

第三个参数总是一个指针,但指针的类型依赖于request
参数。

我们可以把和网络相关的请求划分为6
类:

套接口操作

文件操作

接口操作

ARP
高速缓存操作

路由表操作

流系统

下表列出了网络相关ioctl
请求的request
参数以及arg
地址必须指向的数据类型:

类别

Request

说明

数据类型










SIOCATMARK

SIOCSPGRP

SIOCGPGRP

是否位于带外标记

设置套接口的进程ID
或进程组ID

获取套接口的进程ID
或进程组ID

int

int

int







FIONBIN

FIOASYNC

FIONREAD

FIOSETOWN

FIOGETOWN

设置/
清除非阻塞I/O
标志

设置/
清除信号驱动异步I/O
标志

获取接收缓存区中的字节数

设置文件的进程ID
或进程组ID

获取文件的进程ID
或进程组ID

int

int

int

int

int







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

ARP


SIOCSARP

SIOCGARP

SIOCDARP

创建/
修改ARP
表项

获取ARP
表项

删除ARP
表项

struct arpreq

struct arpreq

struct arpreq







SIOCADDRT

SIOCDELRT

增加路径

删除路径

struct rtentry

struct rtentry




I_xxx

套接口操作:


明确用于套接口操作的ioctl
请求有三个,
它们都要求ioctl
的第三个参数是指向某个整数的一个指针。

SIOCATMARK:
如果本套接口的的度指针当前位于带外标记,那就通过由第三个参数指向的整数返回一个非0
值;否则返回一个0
值。POSIX
以函数sockatmark
替换本请求。

SIOCGPGRP

通过第三个参数指向的整数返回本套接口的进程ID
或进程组ID
,该ID
指定针对本套接口的SIGIO
或SIGURG
信号的接收进程。本请求和fcntl
的F_GETOWN
命令等效,POSIX
标准化的是fcntl
函数。

SIOCSPGRP

把本套接口的进程ID
或者进程组ID
设置成第三个参数指向的整数,该ID
指定针对本套接口的SIGIO
或SIGURG
信号的接收进程,本请求和fcntl
的F_SETOWN
命令等效,POSIX
标准化的是fcntl
操作。

文件操作:


以下5
个请求都要求ioctl
的第三个参数指向一个整数。

FIONBIO

根据ioctl
的第三个参数指向一个0
或非0
值分别清除或设置本套接口的非阻塞标志。本请求和O_NONBLOCK
文件状态标志等效,而该标志通过fcntl
的F_SETFL
命令清除或设置。

FIOASYNC

根据iocl
的第三个参数指向一个0
值或非0
值分别清除或设置针对本套接口的信号驱动异步I/O
标志,它决定是否收取针对本套接口的异步I/O
信号(SIGIO
)。本请求和O_ASYNC
文件状态标志等效,而该标志可以通过fcntl
的F_SETFL
命令清除或设置。

FIONREAD

通过由ioctl
的第三个参数指向的整数返回当前在本套接口接收缓冲区中的字节数。本特性同样适用于文件,管道和终端。

FIOSETOWN

对于套接口和SIOCSPGRP
等效。

FIOGETOWN

对于套接口和SIOCGPGRP
等效。

接口配置:

得到系统中所有接口由SIOCGIFCONF
请求完成,该请求使用ifconf
结构,ifconf
又使用ifreq

结构,如下所示:

Struct ifconf{

int ifc_len; //
缓冲区的大小

union{

caddr_t ifcu_buf; // input from user->kernel

struct ifreq *ifcu_req; // return of structures returned

}ifc_ifcu;

};

#define ifc_buf ifc_ifcu.ifcu_buf //buffer address

#define ifc_req ifc_ifcu.ifcu_req //array of structures returned

#define IFNAMSIZ 16

struct ifreq{

char ifr_name[IFNAMSIZ]; // interface name, e.g., “le0”

union{

struct sockaddr ifru_addr;

struct sockaddr ifru_dstaddr;

struct sockaddr ifru_broadaddr;

short ifru_flags;

int ifru_metric;

caddr_t ifru_data;

}ifr_ifru;

};

#define ifr_addr ifr_ifru.ifru_addr // address

#define ifr_dstaddr ifr_ifru.ifru_dstaddr // otner end of p-to-p link

#define ifr_broadaddr ifr_ifru.ifru_broadaddr // broadcast address

#define ifr_flags ifr_ifru.ifru_flags // flags

#define ifr_metric ifr_ifru.ifru_metric // metric

#define ifr_data ifr_ifru.ifru_data // for use by interface

再调用ioctl
前我们必须先分撇一个缓冲区和一个ifconf
结构,然后才初始化后者。如下图

展示了一个ifconf
结构的初始化结构,其中缓冲区的大小为1024
,ioctl
的第三个参数指向

这样一个ifconf
结构。

ifc_len

Ifc_buf

1024

--------------------->
缓存

假设内核返回2
个ifreq
结构,ioctl
返回时通过同一个ifconf
结构缓冲区填入了那2
个ifreq
结构,ifconf
结构的ifc_len
成员也被更新,以反映存放在缓冲区中的信息量

一般来讲ioctl在用户程序中的调用是:

ioctl(int fd,int command, (char*)argstruct)

ioctl调用与网络编程有关(本文只讨论这一点),文件描述符fd实际上是由socket()系统调用返回的。参数command的取值由/usr/include/linux/sockios.h
所规定。这些command的由于功能的不同,可分为以下几个小类:

• 改变路由表 (例如 SIOCADDRT, SIOCDELRT),

• 读/更新 ARP/RARP 缓存(如:SIOCDARP, SIOCSRARP),

• 一般的与网络接口有关的(例如 SIOCGIFNAME, SIOCSIFADDR 等等)


Gooodies目录下有很多样例程序展示了如何使用ioctl。当你看这些程序时,注意参数argstruct是与参数command相关的。例如,与
路由表相关的ioctl使用rtentry这种结构,rtentry定义在/usr/include/linux/route.h(参见例子
adddefault.c)。与ARP有关的ioctl调用使用arpreq结构,arpreq定义在/usr/include/linux
/if_arp.h(参见例子arpread.c)

与网络接口有关的ioctl调用使用的command参数通常看起来像SIOCxIFyyyy的形式,这里x要
么是S(设定set,写write),要么是G(得到get,读read)。在getifinfo.c程序中就使用了这种形式的command参数来读
IP地址,硬件地址,广播地址和得到与网络接口有关的一些标志(flag)。在这些ioctl调用中,第三个参数是ifreq结构,它在/usr
/include/linux/if.h中定义。在某些情况下,
ioctrl调用可能会使用到在sockios.h之外的新的定义,例如,WaveLAN无线网络卡会保

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: