接口操作——ioctl
来源:互联网 发布:java从文本中读取数据 编辑:程序博客网 时间:2024/06/06 00:15
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
利用SIOCGIFCONF ioctl 实现 get_ifi_info 函数,获取系统的所有处于UP状态的接口信息。
先介绍一下用到的2个结构体:
网络配置接口ifconf
struct ifconf{//网络配置结构体是一种缓冲区
int ifc_len;//缓冲区ifr_buf的大小
union{
char__user *ifcu_buf;//绘冲区指针
struct ifreq__user *ifcu_req;//指向ifreq指针
}ifc_ifcu;
};
#define ifc_buf ifc_ifcu.ifcu_buf;//缓冲区地址
#define ifc_req ifc_ifcu.ifcu_req;//ifc_req地址
网络接口请求结构ifreq
#define IFNAMSIZ16
#define IFHWADDRLEN 6
struct ifreq{
char ifrn_name[IFNAMESIZ];//网络接口名称
union{
struct sockaddr ifru_addr;//本地IP地址
struct sockaddr ifru_dstaddr;//目标IP地址
struct sockaddr ifru_broadaddr;//广播IP地址
struct sockaddr ifru_netmask;//本地子网掩码地址
struct sockaddr ifru_hwaddr;//本地MAC地址
short ifru_flags;//网络接口标记
int ifru_mtu;//最大传输单元
void __user *ifru_data;//用户数据
}ifr_ifru;
}
#define ifr_name ifr_ifrn.ifrn_name;//接口名称
#define ifr_hwaddr ifr_ifru.ifru_hwaddr;//MAC
#define ifr_addr ifr_ifru.ifru_addr;//本地IP
#define ifr_dstaddr ifr_ifru.dstaddr;//目标IP
#define ifr_broadaddr ifr_ifru.broadaddr;//广播IP
#define ifr_netmask ifr_ifru.ifru_netmask;//子网掩码
#define ifr_flags ifr_ifru.ifru_flags;//标志
#define ifr_mtu ifr_ifru.ifru_mtu;//最大传输单元
#define ifr_data ifr_ifru.ifru_data;//接口使用
如果想获得网络接口的相关信息,就传入ifreq结构体.
实例代码:
/*** ifinfo.h ***/#include <sys/types.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <netinet/in.h>#include <arpa/inet.h>#include <net/if.h>#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#define IFI_NAME 16#define IFI_HADDR 8 struct ifi_info{ char ifi_name[IFI_NAME]; short ifi_mtu; short ifi_flags; struct sockaddr *ifi_addr; struct sockaddr *ifi_brdaddr; struct sockaddr *ifi_dstaddr; struct ifi_info *ifi_next;};struct ifi_info*get_ifi_info(){ int sockfd,len,flags; char *buf,*ptr; struct ifconf ifc; struct ifreq *ifr,ifrcopy; struct ifi_info *ifi,*ifihead, **ifipnext; struct sockaddr_in *sinptr; if((sockfd=socket(AF_INET,SOCK_DGRAM,0)) < 0){ printf("socket error\n"); return (struct ifi_info *)0; } len=10*sizeof(struct ifreq); buf=malloc(len); ifc.ifc_len=len; ifc.ifc_buf=buf; if(ioctl(sockfd,SIOCGIFCONF,&ifc) < 0){ printf("ioctl SIOCGIFCONF error\n"); return (struct ifi_info *)0; } ifihead=NULL; ifipnext=&ifihead; for(ptr=buf;ptr<buf+ifc.ifc_len;){ ifr=(struct ifreq *)ptr; ptr += sizeof(ifr->ifr_name)+sizeof(struct sockaddr); if(ifr->ifr_addr.sa_family != AF_INET) continue; ifrcopy=*ifr; if(ioctl(sockfd,SIOCGIFFLAGS,&ifrcopy) < 0){ printf("ioctl SIOCGIFFLAGS error\n"); return (struct ifi_info *)0; } flags=ifrcopy.ifr_flags; if((flags & IFF_UP) == 0) continue; ifi=malloc(sizeof(struct ifi_info)); *ifipnext=ifi; ifipnext=&ifi->ifi_next; ifi->ifi_flags=flags; if(ioctl(sockfd,SIOCGIFMTU,&ifrcopy) < 0){ printf("ioctl SIOCGIFMTU error\n"); return (struct ifi_info *)0; } ifi->ifi_mtu=ifrcopy.ifr_mtu; memcpy(ifi->ifi_name,ifr->ifr_name,IFI_NAME); ifi->ifi_name[IFI_NAME]='\0'; sinptr=(struct sockaddr_in *)&ifr->ifr_addr; ifi->ifi_addr=malloc(sizeof(struct sockaddr_in)); memcpy(ifi->ifi_addr,sinptr,sizeof(struct sockaddr_in)); if(flags &IFF_BROADCAST){ if(ioctl(sockfd,SIOCGIFBRDADDR,&ifrcopy) < 0){ printf("ioctl SIOCGIFBRDADDR error\n"); return (struct ifi_info *)0; } sinptr=(struct sockaddr_in *)&ifrcopy.ifr_broadaddr; ifi->ifi_brdaddr=malloc(sizeof(struct sockaddr_in)); memcpy(ifi->ifi_brdaddr,sinptr,sizeof(struct sockaddr_in)); } if(flags &IFF_POINTOPOINT){ if(ioctl(sockfd,SIOCGIFDSTADDR,&ifrcopy) < 0){ printf("ioctl SIOCGIFDSTADDR error\n"); return (struct ifi_info *)0; } sinptr=(struct sockaddr_in *)&ifrcopy.ifr_dstaddr; ifi->ifi_dstaddr=malloc(sizeof(struct sockaddr_in)); memcpy(ifi->ifi_dstaddr,sinptr,sizeof(struct sockaddr_in)); } } free(buf); return (ifihead);}voidfree_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; free(ifi); }}/*** ifinfo.c ***/#include "ifinfo.h"intmain(int argc ,char **argv){ struct ifi_info *ifi,*ifihead; int i; char buf[32]; struct sockaddr_in *sin; for(ifihead=ifi=get_ifi_info();ifi != NULL;ifi=ifi->ifi_next){ printf("%s",ifi->ifi_name); printf("<"); if(ifi->ifi_flags & IFF_UP) printf("UP "); if(ifi->ifi_flags & IFF_BROADCAST) printf("BCAST "); if(ifi->ifi_flags & IFF_MULTICAST) printf("MCAST "); if(ifi->ifi_flags & IFF_LOOPBACK) printf("LOOP "); if(ifi->ifi_flags & IFF_POINTOPOINT) printf("P2P "); printf(">\n"); if(ifi->ifi_mtu != 0) printf("MTU: %d\n",ifi->ifi_mtu); if(ifi->ifi_addr != NULL){ sin=(struct sockaddr_in *)ifi->ifi_addr; inet_ntop(AF_INET,&sin->sin_addr,buf,sizeof(buf)); printf("IP addr:%s\n",buf); } if(ifi->ifi_brdaddr != NULL){ sin=(struct sockaddr_in *)ifi->ifi_brdaddr; inet_ntop(AF_INET,&sin->sin_addr,buf,sizeof(buf)); printf("broadcast addr:%s\n",buf); } if(ifi->ifi_dstaddr != NULL){ sin=(struct sockaddr_in *)ifi->ifi_dstaddr; inet_ntop(AF_INET,&sin->sin_addr,buf,sizeof(buf)); printf("destination addr:%s\n",buf); } } free_ifi_info(ifihead); exit(0);}
- 接口操作——ioctl
- v4l2 编程接口 — ioctl
- ioctl---操作设备的接口
- v4l2 编程接口(一) — ioctl
- v4l2 编程接口(一) — ioctl
- v4l2 编程接口(一) — ioctl
- v4l2 编程接口(一) — ioctl
- v4l2 编程接口(一) — ioctl
- v4l2 编程接口(一) — ioctl
- v4l2 编程接口(一) — ioctl
- v4l2 编程接口(一) — ioctl
- 高级字符驱动程序操作——ioctl
- ioctl接口
- ioctl操作
- IOCTL操作
- IOCTL操作
- Linux——ioctl
- linux驱动—ioctl
- A|B?
- 我的程序员之路(4)---C语言课程设计
- JAVA读取WORD,EXCEL,POWERPOINT,PDF文件的方法
- 解说一个简单的Win32程序
- java泛型总结
- 接口操作——ioctl
- java通过jxl.jar实现excel导入导出
- OC - 初学01
- iOS 禁止屏幕旋转的方法
- ubuntu10.10系统安装(win7硬盘下安装)
- 字符串、字符相关
- Add a User to a Group (or Second Group) on Linux
- tabhost activity 手势滑动
- 提取EXCEL文本链接中的链接地址