一、函数原型

#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函数的更多相关文章

  1. (十)Linux 网络编程之ioctl函数

    1.介绍 Linux网络程序与内核交互的方法是通过ioctl来实现的,ioctl与网络协议栈进行交互,可得到网络接口的信息,网卡设备的映射属性和配置网络接口.并且还能够查看,修改,删除ARP高速缓存的 ...

  2. IOCTL函数用法

    http://blog.163.com/he_junwei/blog/static/19793764620152510533753/ http://blog.csdn.net/styyzxjq2009 ...

  3. Linux下利用ioctl函数获取网卡信息

    linux下的ioctl函数原型如下: #include <sys/ioctl.h> int ioctl(int handle, int cmd, [int *argc, int argv ...

  4. 文件I/O之ioctl函数

    ioctl函数是I/O操作的杂物箱.不能用其他函数表示的I/O操作通常都能用ioctl表示.终端I/O是ioctl的最大使用方面. ioctl函数通过对文件描述符发送特定的命令来控制文件描述符所代表的 ...

  5. Linux系统编程(4)——文件与IO之ioctl函数

    ioctl是设备驱动程序中对设备的I/O通道进行管理的函数.所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率.马达的转速等等.它的参数个数如下:int ioctl(int ...

  6. UNIX网络编程——ioctl 函数的用法详解

    1.介绍 Linux网络程序与内核交互的方法是通过ioctl来实现的,ioctl与网络协议栈进行交互,可得到网络接口的信息,网卡设备的映射属性和配置网络接口.并且还能够查看,修改,删除ARP高速缓存的 ...

  7. 六、文件IO——fcntl 函数 和 ioctl 函数

    6.1 fcntl 函数 6.1.1 函数介绍 #include <unistd.h> #include <fcntl.h> int fcntl(int fd, int cmd ...

  8. ioctl函数详细说明(网络)

    ioctl 函数 本函数影响由fd 参数引用的一个打开的文件. #include<unistd.h> int ioctl( int fd, int request, .../* void ...

  9. Linux内核的ioctl函数学习

    Linux内核的ioctl函数学习 来源:Linux公社  作者:Linux 我这里说的ioctl函数是在驱动程序里的,因为我不知道还有没有别的场合用到了ioctl, 所以就规定了我们讨论的范围.为什 ...

随机推荐

  1. Python encode和decode

    今天在写一个StringIO.write(int)示例时思维那么一发散就拐到了字符集的问题上,顺手搜索一发,除了极少数以外,绝大多数中文博客都解释的惨不忍睹,再鉴于被此问题在oracle的字符集体系中 ...

  2. git常用命令说明教程

    git常用命令说明教程 git介绍 是一个分布式的,版本控制软件.每台使用git的电脑都是一个分版本库.svn是集中管理的. 安装git 一 git相关操作 1.官网下载最新版安装https://gi ...

  3. 七 Struts2 文件上传和下载

    配置文件 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC &qu ...

  4. .NET 增加扩展方法

    声明:通过一个js的实例来告诉你C#也可以实现这样的效果. 在JS中是这样实现的: 你是否见过JS中给系统默认Array对象增加一个自定义查重方法contains 在没有给Array原型上增加cont ...

  5. iOS 快捷下载和安装并使用CocoaPods

    CocoaPods是什么? 当你开发iOS应用时,会经常使用到很多第三方开源类库,比如JSONKit,AFNetWorking等等.可能某个类库又用到其他类库,所以要使用它,手动一个个去下载所需类库十 ...

  6. Mysql基本命令及数据库存储位置

    连接数据库: sudo mysql -p+密码 例如:sudo mysql -p123456 1.显示数据库列表. show databases; 2.显示库中的数据表: use mysql: //打 ...

  7. 01-Redhat/Centos7网卡命名介绍及修改方式

    1. Redhat/Centos7网卡命名介绍 1.1 网络设备命名 Redhat/Centos7提供在网络接口中使用新的网络设备命名方法.这些功能会更改系统中的网络接口名称,以便定位和区分这些接口. ...

  8. 1、roboguide新建工程文件

    打开roboguide,软件界面如下,接下来讲解一下“打开和新建工程文件” 首先介绍一下新建工程文件,在工具栏中点击新建按钮或者在文件(file)的下拉菜单中点击新建工程文件(new cell),弹出 ...

  9. ThinkPad T400 键帽下面的X支架的安装方法

    有一台古老的T400,清理键盘的时候,X支架老化断了,淘宝买了几个支架,研究一下安装方法: 1.注意支架方向:上面是横向的细支架,下面是两个小孔2.用小螺丝刀把下面的两个小孔推进键盘下面的两个金属钩里 ...

  10. Apache No installed service named "Apache2.4"的解决办法

    windows安装Apache后,用cmd开启apache服务时,提示No installed service named "Apache2.4" 解决步骤: 1.cmd窗口,进入 ...