ioctl 函数

 

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 无线网络卡会保
 

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值