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, 所以就规定了我们讨论的范围.为什 ...
 
随机推荐
- 走进Java Map家族 (1) - HashMap实现原理分析
			
在Java世界里,有一个古老而神秘的家族——Map.从底层架构到上层应用,他们活跃于世界的每一个角落.但是,每次出现时,他们都戴着一张冷硬的面具(接口),深深隐藏着自己的内心.所有人都认识他们,却并非 ...
 - 获取OlapConnection连接
			
目录: 1.获取org.olap4j.OlapConnection对象 2.获取mondrian.olap.Connection对象 一.org.olap4j.OlapConnection对象 说明: ...
 - docker的基本知识
			
Docker 是什么? Docker 是一个开源的应用容器引擎,是基于go语言的,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化. ...
 - MYSQL内置MYSQL数据库中你可以得到的信息
			
1:help_topic 可以查看函数帮助,例如:SELECT * from help_topic WHERE name='concat' 可以查看concat函数. 2:SLOW_LOG 慢查询日 ...
 - ASP.NET Core 2.1与2.2 SignalR CORS 跨域问题
			
将 SignalR 集成到 ASP.NET Core api 程序的时候,按照官方 DEMO 配置完成,本地访问没有问题,但是发布之后一直报跨域问题,本地是这样设置的: Asp.net core 2. ...
 - 利用unittest+ddt进行接口测试(一):简单demo
			
一般进行接口测试时,每个接口的传参都不止一种情况,一般会考虑正向.逆向等多种组合.所以在测试一个接口时通常会编写多条case,而这些case除了传参不同外,其实并没什么区别. 这个时候就可以利用ddt ...
 - BigDecimal比较大小,BigDecimal判断是否为0
			
原文:https://blog.csdn.net/qq_34926773/article/details/83419004 BigDecimal类型的数据,需要比较大小:声明BigDescimal: ...
 - 类String 常用方法
			
字符串当中的常用方法之比较相关的方法 public boolean equals (object obj):将此字符串与指定的对象进行比较(只有参数是字符串并且内容相同才会返回true) public ...
 - Mysql基本命令及数据库存储位置
			
连接数据库: sudo mysql -p+密码 例如:sudo mysql -p123456 1.显示数据库列表. show databases; 2.显示库中的数据表: use mysql: //打 ...
 - php密码对称encrypt加密
			
/** * 对用户的密码进行加密 * @param $password * @param $encrypt //传入加密串,在修改密码时做认证 * @return array/password */ ...