ioctl函数
一、函数原型
#include <unistd.h> int ioctl(int fd, int request, .../* void *arg */); 返回:成功返回0,否则为-
二、和网络相关的请求(request)
(1)套接字操作
(2)文件操作
(3)接口操作
(4)ARP告诉缓存操作
(5)路由表操作
(6)流系统
三、request参数及arg地址必须指向的数据类型

四、案列:获取所有网络设备接口名称
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h> struct ifreq *get_ifreq(); int main(int argc, char **argv)
{
struct ifreq *ifr, *tobefree; ifr = tobefree = get_ifreq(); do {
printf("%s\n", ifr->ifr_name);
ifr++;
} while (ifr->ifr_name[] != ); free(tobefree); exit();
} struct ifreq *get_ifreq()
{
int sockfd, len, lastlen;
char *buf;
struct ifconf ifc; sockfd = socket(AF_INET, SOCK_DGRAM, ); lastlen = ;
len = * sizeof(struct ifreq); /* initial buffer size guess */
for ( ; ; ) {
buf = malloc(len);
ifc.ifc_len = len;
ifc.ifc_buf = buf;
if (ioctl(sockfd, SIOCGIFCONF, &ifc) < ) {
if (errno != EINVAL || lastlen != ) {
perror("ioctl");
exit(-);
}
} else {
if (ifc.ifc_len == lastlen) {
break; /* success, len has not changed */
}
lastlen = ifc.ifc_len;
}
len += * sizeof(struct ifreq); /* increment */
free(buf);
} return ((struct ifreq *)ifc.ifc_buf);
}
五、关于ioctl函数应该注意


六、get_ifi_info函数
#include "unpifi.h" struct ifi_info *get_ifi_info(int family, int doaliases)
{
int sockfd, len, lastlen, flags, myflags, idx = , hlen = ;
char *ptr, *buf, lastname[IFNAMSIZ], *cptr, *haddr, *sdlname;
struct ifconf ifc;
struct ifreq *ifr, ifrcopy;
struct sockaddr_in *sinptr;
struct sockaddr_in6 *sin6ptr;
struct ifi_info *ifi, *ifihead, **ifipnext; sockfd = socket(family, SOCK_DGRAM, ); lastlen = ;
len = * sizeof(struct ifreq); /* initial buffer size guess */
for ( ; ; ) {
buf = malloc(len);
ifc.ifc_len = len;
ifc.ifc_buf = buf;
if (ioctl(sockfd, SIOCGIFCONF, &ifc) < ) {
if (errno != EINVAL || lastlen != ) {
perror("ioctl");
exit(-);
}
} else {
if (ifc.ifc_len == lastlen) {
break; /* success, len has not changed */
}
lastlen = ifc.ifc_len;
}
len += * sizeof(struct ifreq); /* increment */
free(buf);
}
ifihead = NULL;
ifipnext = &ifihead;
lastname[] = ;
sdlname = NULL; for (ptr = buf; ptr < buf + ifc.ifc_len; ) {
ifr = (struct ifreq *) ptr; #ifdef HAVE_SOCKADDR_SA_LEN
len = max(sizeof(struct sockaddr), ifr->ifr_addr.sa_len);
#else
switch (ifr->ifr_addr.sa_family) {
#ifdef IPV6
case AF_INET6:
len = sizeof(struct sockaddr_in6);
break;
#endif
case AF_INET:
default:
len = sizeof(struct sockaddr);
break;
}
#endif /* HAVE_SOCKADDR_SA_LEN */ ptr += sizeof(ifr->ifr_name) + len + ; /* for next one in buffer */ #ifdef HAVE_SOCKADDR_DL_STRUCT
/* assumes that AF_LINK precedes AF_INET or AF_INET6 */
if (ifr->ifr_addr.sa_family == AF_LINK) {
struct sockaddr_dl *sdl = (struct sockaddr_dl *)&ifr->ifr_addr;
sdlname = ifr->ifr_name;
idx = sdl->sdl_index;
haddr = sdl->sdl_data + sdl->sdl_nlen;
hlen = sdl->sdl_alen;
}
#endif if (ifr->ifr_addr.sa_family != family) {
continue; /* ignore if not desired address family */
} myflags = ;
if ( (cptr = strchr(ifr->ifr_name, ':')) != NULL) {
*cptr = ; /* replace colon with null */
}
if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == ) {
if (doaliases == )
continue; /* already processed this interface */
myflags = IFI_ALIAS;
}
memcpy(lastname, ifr->ifr_name, IFNAMSIZ); ifrcopy = *ifr;
ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy);
flags = ifrcopy.ifr_flags;
if ((flags & IFF_UP) == ) {
continue; /* ignore if interface not up */
} ifi = calloc(, sizeof(struct ifi_info));
*ifipnext = ifi; /* prev points to this new one */
ifipnext = &ifi->ifi_next; /* pointer to next one goes here */ ifi->ifi_flags = flags; /* IFF_xxx values */
ifi->ifi_myflags = myflags; /* IFI_xxx values */
#if defined(SIOCGIFMTU) && defined(HAVE_STRUCT_IFREQ_IFR_MTU)
ioctl(sockfd, SIOCGIFMTU, &ifrcopy);
ifi->ifi_mtu = ifrcopy.ifr_mtu;
#else
ifi->ifi_mtu = ;
#endif
memcpy(ifi->ifi_name, ifr->ifr_name, IFI_NAME);
ifi->ifi_name[IFI_NAME-] = '\0';
/* If the sockaddr_dl is from a different interface, ignore it */
if (sdlname == NULL || strcmp(sdlname, ifr->ifr_name) != ) {
idx = hlen = ;
}
ifi->ifi_index = idx;
ifi->ifi_hlen = hlen;
if (ifi->ifi_hlen > IFI_HADDR) {
ifi->ifi_hlen = IFI_HADDR;
}
if (hlen) {
memcpy(ifi->ifi_haddr, haddr, ifi->ifi_hlen);
} switch (ifr->ifr_addr.sa_family) {
case AF_INET:
sinptr = (struct sockaddr_in *) &ifr->ifr_addr;
ifi->ifi_addr = calloc(, sizeof(struct sockaddr_in));
memcpy(ifi->ifi_addr, sinptr, sizeof(struct sockaddr_in)); #ifdef SIOCGIFBRDADDR
if (flags & IFF_BROADCAST) {
ioctl(sockfd, SIOCGIFBRDADDR, &ifrcopy);
sinptr = (struct sockaddr_in *) &ifrcopy.ifr_broadaddr;
ifi->ifi_brdaddr = calloc(, sizeof(struct sockaddr_in));
memcpy(ifi->ifi_brdaddr, sinptr, sizeof(struct sockaddr_in));
}
#endif #ifdef SIOCGIFDSTADDR
if (flags & IFF_POINTOPOINT) {
ioctl(sockfd, SIOCGIFDSTADDR, &ifrcopy);
sinptr = (struct sockaddr_in *) &ifrcopy.ifr_dstaddr;
ifi->ifi_dstaddr = calloc(, sizeof(struct sockaddr_in));
memcpy(ifi->ifi_dstaddr, sinptr, sizeof(struct sockaddr_in));
}
#endif
break; case AF_INET6:
sin6ptr = (struct sockaddr_in6 *) &ifr->ifr_addr;
ifi->ifi_addr = calloc(, sizeof(struct sockaddr_in6));
memcpy(ifi->ifi_addr, sin6ptr, sizeof(struct sockaddr_in6)); #ifdef SIOCGIFDSTADDR
if (flags & IFF_POINTOPOINT) {
ioctl(sockfd, SIOCGIFDSTADDR, &ifrcopy);
sin6ptr = (struct sockaddr_in6 *) &ifrcopy.ifr_dstaddr;
ifi->ifi_dstaddr = calloc(, sizeof(struct sockaddr_in6));
memcpy(ifi->ifi_dstaddr, sin6ptr, sizeof(struct sockaddr_in6));
}
#endif
break; default:
break;
}
}
free(buf);
return (ifihead); /* pointer to first structure in linked list */
} void free_ifi_info(struct ifi_info *ifihead)
{
struct ifi_info *ifi, *ifinext; for (ifi = ifihead; ifi != NULL; ifi = ifinext) {
if (ifi->ifi_addr != NULL) {
free(ifi->ifi_addr);
}
if (ifi->ifi_brdaddr != NULL) {
free(ifi->ifi_brdaddr);
}
if (ifi->ifi_dstaddr != NULL) {
free(ifi->ifi_dstaddr);
}
ifinext = ifi->ifi_next; /* can't fetch ifi_next after free() */
free(ifi); /* the ifi_info{} itself */
}
} struct ifi_info *Get_ifi_info(int family, int doaliases)
{
struct ifi_info *ifi; if ( (ifi = get_ifi_info(family, doaliases)) == NULL) {
printf("get_ifi_info error\n");
exit(-);
}
return(ifi);
}
七、unpifi.h头文件
#ifndef __unp_ifi_h
#define __unp_ifi_h #include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sys/ioctl.h> #define IFI_NAME 16 /* same as IFNAMSIZ in <net/if.h> */
#define IFI_HADDR 8 /* allow for 64-bit EUI-64 in future */ struct ifi_info {
char ifi_name[IFI_NAME]; /* interface name, null-terminated */
short ifi_index; /* interface index */
short ifi_mtu; /* interface MTU */
u_char ifi_haddr[IFI_HADDR]; /* hardware address */
u_short ifi_hlen; /* # bytes in hardware address: 0, 6, 8 */
short ifi_flags; /* IFF_xxx constants from <net/if.h> */
short ifi_myflags; /* our own IFI_xxx flags */
struct sockaddr *ifi_addr; /* primary address */
struct sockaddr *ifi_brdaddr; /* broadcast address */
struct sockaddr *ifi_dstaddr; /* destination address */
struct ifi_info *ifi_next; /* next of these structures */
}; #define IFI_ALIAS 1 /* ifi_addr is an alias */ /* function prototypes */
char *sock_ntop_host(const struct sockaddr *, socklen_t);
void free_ifi_info(struct ifi_info *);
struct ifi_info *get_ifi_info(int, int);
struct ifi_info *Get_ifi_info(int, int); #endif /* __unp_ifi_h */
八、sock_ntop_host函数
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/un.h> #ifdef HAVE_SOCKADDR_DL_STRUCT
#include <net/if_dl.h>
#endif char *sock_ntop_host(const struct sockaddr *sa, socklen_t salen)
{
static char str[]; /* Unix domain is largest */ switch (sa->sa_family) {
case AF_INET: {
struct sockaddr_in *sin = (struct sockaddr_in *) sa; if (inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str)) == NULL)
return(NULL);
return(str);
} #ifdef IPV6
case AF_INET6: {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; if (inet_ntop(AF_INET6, &sin6->sin6_addr, str, sizeof(str)) == NULL)
return(NULL);
return(str);
}
#endif #ifdef AF_UNIX
case AF_UNIX: {
struct sockaddr_un *unp = (struct sockaddr_un *) sa; /* OK to have no pathname bound to the socket: happens on
every connect() unless client calls bind() first. */
if (unp->sun_path[] == )
strcpy(str, "(no pathname bound)");
else
snprintf(str, sizeof(str), "%s", unp->sun_path);
return(str);
}
#endif #ifdef HAVE_SOCKADDR_DL_STRUCT
case AF_LINK: {
struct sockaddr_dl *sdl = (struct sockaddr_dl *) sa; if (sdl->sdl_nlen > )
snprintf(str, sizeof(str), "%*s",
sdl->sdl_nlen, &sdl->sdl_data[]);
else
snprintf(str, sizeof(str), "AF_LINK, index=%d", sdl->sdl_index);
return(str);
}
#endif
default:
snprintf(str, sizeof(str), "sock_ntop_host: unknown AF_xxx: %d, len %d",
sa->sa_family, salen);
return(str);
}
return (NULL);
}
ioctl函数的更多相关文章
- (十)Linux 网络编程之ioctl函数
1.介绍 Linux网络程序与内核交互的方法是通过ioctl来实现的,ioctl与网络协议栈进行交互,可得到网络接口的信息,网卡设备的映射属性和配置网络接口.并且还能够查看,修改,删除ARP高速缓存的 ...
- IOCTL函数用法
http://blog.163.com/he_junwei/blog/static/19793764620152510533753/ http://blog.csdn.net/styyzxjq2009 ...
- Linux下利用ioctl函数获取网卡信息
linux下的ioctl函数原型如下: #include <sys/ioctl.h> int ioctl(int handle, int cmd, [int *argc, int argv ...
- 文件I/O之ioctl函数
ioctl函数是I/O操作的杂物箱.不能用其他函数表示的I/O操作通常都能用ioctl表示.终端I/O是ioctl的最大使用方面. ioctl函数通过对文件描述符发送特定的命令来控制文件描述符所代表的 ...
- Linux系统编程(4)——文件与IO之ioctl函数
ioctl是设备驱动程序中对设备的I/O通道进行管理的函数.所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率.马达的转速等等.它的参数个数如下:int ioctl(int ...
- UNIX网络编程——ioctl 函数的用法详解
1.介绍 Linux网络程序与内核交互的方法是通过ioctl来实现的,ioctl与网络协议栈进行交互,可得到网络接口的信息,网卡设备的映射属性和配置网络接口.并且还能够查看,修改,删除ARP高速缓存的 ...
- 六、文件IO——fcntl 函数 和 ioctl 函数
6.1 fcntl 函数 6.1.1 函数介绍 #include <unistd.h> #include <fcntl.h> int fcntl(int fd, int cmd ...
- ioctl函数详细说明(网络)
ioctl 函数 本函数影响由fd 参数引用的一个打开的文件. #include<unistd.h> int ioctl( int fd, int request, .../* void ...
- Linux内核的ioctl函数学习
Linux内核的ioctl函数学习 来源:Linux公社 作者:Linux 我这里说的ioctl函数是在驱动程序里的,因为我不知道还有没有别的场合用到了ioctl, 所以就规定了我们讨论的范围.为什 ...
随机推荐
- jqery autocomplete 动态传递参数的问题
今天弄一个autocomplete 向后后台动态传递参数的问题 老的写法: params: { "saleid": $("#divSalesman input[field ...
- mysql的使用相关问题
MySQL的使用和密码忘记解决 解决步骤: 1.查看:我的电脑--管理--服务--查看mysql路径---一直到mysql下的bin文件夹 或需转回别的磁盘: G: (C:\Users\Adm ...
- Django入门之路
Web框架开发-Django基础之web应用,Http协议 web框架开发-web框架简介,wsgiref模块,DIY一个web框架 web框架开发-Django简介 web框架开发-静态文件配置 w ...
- .NET Core 图片操作在 Linux/Docker 下的坑
一.前言 .NET Core 目前更新到2.2了,但是直到现在在 .NET Core 本身依然不包括和图片有关的 Image.Bitmap 等类型.对于图片的操作在我们开发中很常见,比如:生成验证码. ...
- 2018-2019 ACM-ICPC, Asia East Continent Finals I. Misunderstood … Missing(dp)
题目链接: http://codeforces.com/gym/102056/problem/I 题意: 人物有l两个属性分别是$A,D$ 每个回合人物$A\pm D$ 每个回合有三个选择分别是: 1 ...
- ubuntu下安装Visual Studio Code
环境准备 先安装一般umake没有问题 sudo add-apt-repository ppa:ubuntu-desktop/ubuntu-make sudo apt-get update sudo ...
- 软工+C(9): 助教指南,持续更新...
上一篇:提问与回复 下一篇:从命令行开始逐步培养编程能力(Java) 目录: ** 0x00 Handshake ** 0x01 点评 ** 0x02 评分 ** 0x03 知识储备 ** 0x04 ...
- 【转】Linux之crontab定时任务命令
1. crontab命令概念 crontab命令用于设置周期性被执行的指令.该命令从标准输入设备读取指令,并将其存放于“crontab”文件中,以供之后读取和执行. cron 系统调度进程. 可以使 ...
- Angular 基本内置服务和筛选器
AngularJS中的内置服务(共30多个): $http 发送http请求,主要用于进行异步数据请求的功能实现,这个服务主要封装了XMLHttpRequest对象和JSONP数据访问模式来完成远程请 ...
- Jmeter日志级别
转自:https://blog.csdn.net/gowhere_/article/details/78555068 Jmeter日志默认存放在%JMeter_HOME%\bin目录,文件名通常是JM ...