ioctl函数

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

本函数影响由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成员也被更新,以反映存放在缓冲区中的信息量。接口操作:

SIOCGIFCONF请求为每个已配置的接口返回其名字以及一个套接口地址结构。我们接着可以发出多个接口类其他请求以设置或获取每个接口的其他特征。这些请求的获取(get)版本(SIOCGxxx)通常由netstat程序发出,设置(set)版本(SIGOCSxxx)通常由ifconfig程序发出。任何用户都可以获取接口信息,设置接口信息却要求有超级用户权限。

 

这些请求汲取或返回一个一个ifreq结构中的信息,而这个结构的地址则作为ioctl调用的第三个参数制定。接口总是以其名标志,在ifreq结构的ifr_name成员中指定,如le0,lo0,ppp0等。

这些请求中有许多使用套接口地址结构在应用进程和内核之间指定或返回具体接口的IP地址或地址掩码。对于IPV4,这个地址或掩码放在一个网际套接口地址结构的sin_addr成员中;对于IPV6,它是一个IPV6套接口地址结构的sin6_addr成员。

 

SIOCGIFADDR:  在ifr_addr成员中返回单播地址。

SIOCSIFADDR:用ifr_addr成员设置接口地址,这个接口的初始化函数也被调用。

 

SIOCGIFFLAGS:在ifr_flags成员中返回接口标志。这些接口标志的名字格式为IFF_XXX,在<net/if.h>头文件中定义。举例来说,这些标志指示接口是否处于UP即在工状态(IFF_UP),是否为一个点到点接口(IFF_POINTOPOINT),是否支持广播(IFF_BROADCAST),等等。

SIOCSIFFLAGS:用ifr_flags成员设置接口标志。

SIOCGIFDSTADDR:在ifr_dstaddr成员中返回点到点地址。

SIOCSIFDSTADDR:  在ifr_dstaddr成员中设置点到点地址

SIOCGIFBRDADDR:  在ifr_broadaddr成员中返回广播地址。应用进程必须首先获取接口标志,然后发出正确的请求;对于广播接口为SIOCGIFBRDADDR,对于点到点接口为SIOCGIFDSTADDR

SIOCSIFBRDADDR:用ifr_broadaddr成员设置广播地址。

SIOCGIFNETMASK:在ifr_addr成员中返回子网掩码。

SIOCSIFNETMASK:在ifr_addr成员中设置子网掩码。

SIOCGIFMETRIC:用ifr_metric成员返回接口测度。接口测度由内核为每个接口维护,不过使用他的是路由守护进程routed。接口测度被routed加到跳数上。

SIOCSIFMETRIC:用ifr_metric成员设置接口的路由测度。

 

 

 

ARP高速缓存操作

ARP告诉缓存也通过ioctl函数操纵。使用路由域套接口的系统往往改用路由套接口访问

ARP高速缓存。这些请求使用如下的arpreq结构,定义在<net/if_arp.h>

 

struct arpreq {

    struct sockaddr      arp_pa;

    struct sockaddr      arp_ha;

    int                  arp_flags;

};

 

#define ATF_INUSE      0x01   //entry in use

#define ATF_COM         0x02   //completed entry (hardware addr valid)

#define ATF_PERM       0x04   // permanent entry

#define ATF_PUBL 0x08   // published entry (respond for other host )

 

Ioctl的第三个必须指向某个arpreq结构,操纵ARP高速缓存的ioctl请求有以下三个:

 

SIOCSARP:           把一个新的表项加入ARP告诉缓存中区,或者修改其中已经存在的一个表项,其中arp_pa是一个含有IP地址的网际套接口地址结构,arp_ha则是一个通用套接口地址结构,他的sa_family值为AF_unspec,sa_data中含有硬件地址(例如6直接的以太网地址)。ATF_PERM和ATF_PUBL这两个标志也可以由应用进程指定。另外两个标志(ATF_INUSE和ATF_COM)则由内核设置。

SIOCDARP:        从ARP告诉缓存中删除一个表项。调用者指定要删除表项的网际地址。

SIOCGARP:        从ARP高速缓存中获取一个表项。调用者指定网际地址,相应的硬件地址(例外以太网地址)随标志一起返回。

 

只有超级用户才能增加或删除表项。这三个请求通常由arp程序发出。

注意ioctl没有办法列出ARP高速缓存中的所有表项。当指定-a标志执行arp命令时,大多

数版本的arp程序通过读取内核的内存( /dev/kmem )获得ARP高速缓存的当前内容。

 

路由表操作 

有些系统提供2个用于操纵路由表的ioctl请求。这2个请求要求ioctl的第三个参数是指向

某个rtentry结构的一个指针,该结构定义在<net/route.h>头文件中。这些请求通常由route

程序发出。只有超级用户才能发出这些请求。

SIOCADDRT:往路由表中增加一个表项

SIOCDELRT:从路由表中删除一个表项

Ioctl没有办法列出路由表中的所有表项。这个操作通常由netstat程序在指定-r标志自行四

完成。netstat程序通过读取内核的内存  (/dev/kmem)获得整个路由表。用sysctl同样可

以做到。

 

 

如下是chinaunix论坛飞灰橙给出的一个例子。

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <net/if.h>

#include <net/if_arp.h>

#include <sys/ioctl.h>

#include <netinet/in.h>

void err_sys(const char *errmsg);

int main(void)

{               

        int i, sockfd;

        struct ifreq ifr;

        struct arpreq arpr;

      

        strncpy(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name));

      

        if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1)

                err_sys("socket");      

      

        /* get ip address */

        if (ioctl(sockfd, SIOCGIFADDR, &ifr) == -1)      

                err_sys("1-ioctl");

      

        /* get hardware address */

                ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;

        if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) == -1)

                err_sys("2-ioctl");

      

        /* output hardware address */

        for (i = 0; i < 6; i++) {

                        unsigned char *mac = (unsigned char *) ifr.ifr_hwaddr.sa_data;

                printf("%x", (int) mac[i]);

                if (i != 5)

                        printf("%c", ':');

        }

        exit(0);

}

void err_sys(const char *errmsg)

{

        perror(errmsg);

      

        exit(1);

}

arm linux 蜂鸣器qt,Qt 程序中使用蜂鸣器 ioctl() 在最近的项目中,由于使用的显示屏的触摸效果不是很好,有时触摸的力度小了,就没反应,用户的手指有挡住了按键,不能看到按键按下的时的效果。于是就提出了在按键触发效果时蜂鸣器就叫一下。在几经查找资料后,发现了ioctl()函数,能很好的控制I/O设备。函数名:ioctl()头文件:#include用 法:int ioctl(int fd,unsigned int cmd,[int *argdx, i... 阅读详情

相关推荐

一次意外的ioctl调用错误—论不同版本内核的ioctl函数实现

前言          人要经常学会反思总结,这样才能不断的进步。同样,一个合格优秀的软件工程师也需要经常的总结反思自己工作中遇到的问题,这样才能使自己的能力不断的提升。我从来不给自己定位为程序猿,多年后,请叫我软件工程师乃至软件架构师,哈哈,又装逼了我!纵使我现在还年轻,能力阅历还未达到大师级别,但是人要有梦想,万一实现了呢?可是相比较梦想,我觉得有目标比较实际。卧槽,每次写博客都是这样,先是

yang blog 1万+

ubuntu18.04 在QT下调用V4L2的ioctl函数来实现采集视频流 把采集到的视频流在控件上显示出来 同时采集两个相机

在ubuntu18.04系统;利用V4L2采集两个usb摄像头数据,在QT上控件显示两个采集的视频流。可以同时采集两个相机。 在QT下调用V4L2的库函数来实现采集视频流。并且把采集到的视频流在控件上显示出来。 相机输出格式可以设置为JPEG(V4L2_PIX_FMT_MJPEG),也可设置为yuyv(V4L2_PIX_FMT_YUYV),程序里面有介绍。 程序里面使用的是ioctlioctl是应用与驱动的常用接口。对字符设备、块设备、及套接字,非常方便扩充新的命令)。 QT版本(qt-opensource-linux-x64-5.13.2)。 使用了QT的线程, 相机的整个采图过程在子线程中进行,可以避免卡住主线程。 并且把抓到的图转为QImage对象,方便后续的处理,可以方便的保存为图片,例如BMP图片。

Qt程序中使用ioctl控制蜂鸣器

我们使用了Linux系统中的蜂鸣器设备文件"/dev/console",并通过ioctl函数发送相应的操作来控制蜂鸣器的行为。在Qt程序中,我们可以使用ioctl函数来控制蜂鸣器的行为。本文将介绍如何在Qt程序中使用ioctl函数来控制蜂鸣器,并提供相应的源代码示例。在Qt程序中,我们可以通过打开特定的设备文件来控制蜂鸣器。ioctl函数的第一个参数是设备文件的文件描述符,第二个参数是要执行的操作,第三个参数是一个指向操作数的指针。在上面的代码中,我们将频率和持续时间作为操作数传递给ioctl函数

DevForge的博客 646

Linux内核编程(五)ioctl驱动编写

ioctl主要用于实现对硬件设备控制类操作,实现 write 和 read 不太好实现的功能。ioctl是一个强大的工具,可以用于实现复杂的设备控制和状态查询。尽管它的使用有时被认为不太优雅,因为它打破了标准的读写接口模型,但在许多情况下,它提供了一种有效的方法来与设备驱动程序进行高级交互。开发者在使用 ioctl 时需要小心设计和实现命令码,以确保与设备的交互是清晰且安全的。

qq_1033275663的博客 1704

Qtioctl

今天在将HPI驱动移植到QT中的时候发现,ioctl函数怎么都调用不到,网上各种查啊。 先是得到linux内核版本变化导致的ioctl函数被换成了unlocked_ioctl,然后发现在应用程序中调用ioctl还是不行, 然后查看ioctl-number.txt 修改魔数,换成了里面没有用到的‘x’。然后修改cmd的宏 #define Write_HPIC      _IOW(HPI_MAG

zhang2531的专栏 3911

Qt中使用ioctl函数返回值-1错误

在我之前的开发板上运行我的Qt程序进行spi通信时,没有错误可以通信。 现在在新的开发板上运行同样的Qt程序进行SPI通信时却有错误,出错误的函数为图 串口会打印ret=-1,我想问一下什么情况下会返回-1这个值,是我没驱动起SPI来还是我的SPI的引脚没有配置好呢?该怎么排除解决这个问题呢? ...

UPCWYH0624的博客 1271

IOCTL函数用法详解

ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。它的调用个数如下:  int ioctl(int fd, ind cmd, …);      其中fd是用户程序打开设备时使用open函数返回的文件标示符,cmd是用户程序对设备的控制命令,至于后面的省略号,那是一些补充参数,一般最多一个,这

9527的专栏 2万+

ioctl()函数详解

我这里说的ioctl函数是指驱动程序里的,因为我不知道还有没有别的场合用到了它,所以就规定了我们讨论的范围。写这篇文章是因为我前一阵子被ioctl给搞混了,这几天才弄明白它,于是在这里清理一下头脑。 一、 什么是ioctl      ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。它的

shanshanpt的专栏 21万+

ioctl函数介绍

我这里说的ioctl函数是在驱动程序里的,因为我不知道还有没有别的场合用到了ioctl, 所以就规定了我们讨论的范围。为什么要写篇文章呢,是因为我前一阵子被ioctl给搞混 了,这几天才弄明白它,于是在这里清理一下头脑。 一、 什么是ioctlioctl是设备驱动程序中对设备的I/O通道进行管理的函数。所谓对I/O通道进行管理,就

Humwen 6185

ioctl函数讲解

每个设备驱动会。

2301_80094394的博客 1672

ioctl函数的作用

ioctl函数的作用 特殊的read,write, 当你用read,write不能完成某一功能时,就用ioctl 我这里说的ioctl函数是在驱动程序里的,因为我不知道还有没有别的场合用到了ioctl,所以就规定了我们讨论的范围。为什么要写篇文章呢,是因为我前一阵子被ioctl给搞混了,这几天才弄明白它,于是在这里清理一下头脑。 什么是ioctlioctl是设备驱动程序中对设备...

whoami 5625

ioctl函数的使用

主题:ioctl函数详细说明<br />ioctl 函数<br /> <br />本函数影响由fd 参数引用的一个打开的文件。<br /> <br />#include<unistd.h><br />int ioctl( int fd, int request, .../* void *arg */ );<br />返回0 :成功    -1 :出错<br /> <br />第三个参数总是一个指针,但指针的类型依赖于request 参数。<br />我们可以把和网络相关的请求划分为6 类:<br />套接口

kdtiankong的专栏 255

ioctl()函数

函数影响由fd参数引用的一个打开的文件。 #include#include int ioctl( int fd, int request, .../* void *arg */ );返回0:成功    -1:出错 第三个参数总是一个指针,但指针的类型依赖于request参数。我们可以把和网络相关的请求划分为6类:套接口操作文件操作接口操作ARP高速

hecant的专栏 4485

IOCTL函数

来公司实习看代码的时候经常会看到IOCTL这个函数,以前没见过,也问过mentor一回,但一直没搞懂,今天就拿出一点时间查了一下。 首先看一下ioctl函数原型:                 int ioctl(int fd, int cmd, [int *argdx, int *argcx])                    返回值:成功为0,出错为-1。

woaiajiao的专栏 949

linux 内核 - ioctl 函数详解

linux 内核 - ioctl 函数详解 1. 概念 ioctl 是设备驱动程序中设备控制接口函数,一个字符设备驱动通常会实现设备打开、关闭、读、写等功能,在一些需要细分的情境下,如果需要扩展新的功能,通常以增设 ioctl() 命令的方式实现。 在文件 I/O 中,ioctl 扮演着重要角色,本文将以驱动开发为侧重点,从用户空间到内核空间纵向分析 ioctl 函数。 2. 用户空间 ioctl #include <sys/ioctl.h> int ioctl(int fd, int cm

JCfyw的博客 5166

linux ioctl()函数详解

转载:http://www.cnblogs.com/geneil/archive/2011/12/04/2275372.html 一、 什么是ioctl      ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。它的调用个数如下:  int ioctl(int fd, ind cmd,

Invoker's Tower 2万+
上一篇: Socket描述符选项[SOL_SOCKET]
下一篇: FILE__,__LINE__,FUNCTION__实现代码跟踪调试(linux下c语言编程 )
linuxerhqt
博客等级 码龄15年 8粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值