接口操作——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);}



原创粉丝点击