[위 에] ioctl 과 struct ifreq

다음으로 이동:http://tech.sunplusedu.com/space/post-4064.aspx
 
ioctl 로 로 컬 ip 주 소 를 얻 을 때 두 개의 구조 체 ifconf 와 ifreq 를 사용 해 야 합 니 다. 대부분 사람들 에 게 낯 설 습 니 다. 여 기 는 여러분 에 게 비교적 간단 한 이해 방법 을 제공 합 니 다. 물론 이해 하 는 데 도움 이 되 는 방법 만 있 습 니 다. 설명 에서 진실 한 정의 와 차이 가 있 을 수 있 습 니 다. 참고 하 시기 바 랍 니 다.
우선 ifconf 와 ifreq 를 알 아 보 세 요.
//ifconf              
//if.h
struct ifconf 
{
    int    ifc_len;            /* size of buffer    */
    union 
    {
        char *ifcu_buf;                        /* input from user->kernel*/
        struct ifreq *ifcu_req;        /* return from kernel->user*/
    } ifc_ifcu;
};
#define    ifc_buf    ifc_ifcu.ifcu_buf        /* buffer address    */
#define    ifc_req    ifc_ifcu.ifcu_req        /* array of structures    */
 
//ifreq           
//if.h
struct ifreq {
    char ifr_name[IFNAMSIZ];
    union {
        struct sockaddr ifru_addr;
        struct sockaddr ifru_dstaddr;
        struct sockaddr ifru_broadaddr;
        short ifru_flags;
        int ifru_metric;
        caddr_t ifru_data;
    } ifr_ifru;
};
#define ifr_addr ifr_ifru.ifru_addr
#define ifr_dstaddr ifr_ifru.ifru_dstaddr
#define ifr_broadaddr ifr_ifru.ifru_broadaddr

 
위의 두 구 조 는 비교적 복잡 해 보인다. 우 리 는 지금 그것들 을 간단하게 한다. 예 를 들 어 지금 우 리 는 로 컬 IP 를 얻 는 기능 을 실현 하고 있다.
우리 의 방법 은: 1. 먼저 ioctl 을 통 해 로 컬 의 모든 인터페이스 정 보 를 얻 고 ifconf 에 저장 합 니 다. 2. ifconf 에서 모든 ifreq 에서 ip 주 소 를 표시 하 는 정 보 를 꺼 냅 니 다.
구체 적 으로 사용 할 때 우 리 는 ifconf 에 두 명의 구성원 이 있다 고 생각 할 수 있다. ifclen 과 ifcbuf,
 
ifc_len: 모든 인터페이스 정 보 를 저장 하 는 버퍼 길이 ifcbuf: 인터페이스 정 보 를 저장 하 는 버퍼
그래서 프로그램 이 시 작 될 때 ifconf 에 대한 ifc 가 필요 합 니 다.len 과 ifcbuf 초기 화 다음 ioctl 을 사용 하여 모든 인터페이스 정 보 를 가 져 옵 니 다. 완료 후 ifclen 은 실제 획득 한 인터페이스 정보의 총 길 이 를 저장 하고 정 보 는 ifc 에 저 장 됩 니 다.buf 중.
다음 에 우 리 는 하나의 인터페이스 정보 에서 ip 주소 정 보 를 얻 으 면 된다.
다음은 간단 한 참고 가 있 습 니 다.
 
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main()
{
int i=0;
int sockfd;
struct ifconf ifconf;
unsigned char buf[512];
struct ifreq *ifreq;
//   ifconf
ifconf.ifc_len=512;
ifconf.ifc_buf=buf;
if((sockfd=socket(AF_INET,SOCK_DGRAM,0))<0)
{
perror("socket");
exit(1);
}
ioctl(sockfd,SIOCGIFCONF,&ifconf);//        
//          IP  
ifreq=(struct ifreq*)buf;
for(i=(ifconf.ifc_len/sizeof(struct ifreq));i>0;i--)
{
// if(ifreq->ifr_flags == AF_INET){ //for ipv4
printf("name = %s 
", ifreq->ifr_name); printf("local addr = %s
",inet_ntoa(((struct sockaddr_in*)&(ifreq->ifr_addr))->sin_addr)); ifreq++; // } } return 0; }

 
 
 
이 방법 은 참고 만 제공 하고 다른 정 보 를 얻 는 데 도 적용 된다.
다음http://woxihuanpes.blog.163.com/blog/static/12423219820098715741431/
struct ifreq
이 구 조 는 / usr / include / net / if. h 에 정의 되 어 있 으 며, ip 주 소 를 설정 하고 인 터 페 이 스 를 활성화 하 며, MTU 등 인터페이스 정 보 를 설정 합 니 다.
 
DE>/* Interface request structure used for socket ioctl's. All interface    ioctl's must have parameter definitions which begin with ifr_name.    The remainder may be interface specific. */ struct ifreq   { # define IFHWADDRLEN 6 # define IFNAMSIZ IF_NAMESIZE     union       {         char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "en0". */       } ifr_ifrn;     union       {         struct sockaddr ifru_addr;         struct sockaddr ifru_dstaddr;         struct sockaddr ifru_broadaddr;         struct sockaddr ifru_netmask;         struct sockaddr ifru_hwaddr;         short int ifru_flags;         int ifru_ivalue;         int ifru_mtu;         struct ifmap ifru_map;         char ifru_slave[IFNAMSIZ]; /* Just fits the size */         char ifru_newname[IFNAMSIZ];         __caddr_t ifru_data;       } ifr_ifru;   }; # define ifr_name ifr_ifrn.ifrn_name /* interface name */ # define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */ # define ifr_addr ifr_ifru.ifru_addr /* address */ # define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-p lnk */ # define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */ # define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */ # define ifr_flags ifr_ifru.ifru_flags /* flags */ # define ifr_metric ifr_ifru.ifru_ivalue /* metric */ # define ifr_mtu ifr_ifru.ifru_mtu /* mtu */ # define ifr_map ifr_ifru.ifru_map /* device map */ # define ifr_slave ifr_ifru.ifru_slave /* slave device */ # define ifr_data ifr_ifru.ifru_data /* for use by interface */ # define ifr_ifindex ifr_ifru.ifru_ivalue /* interface index */ # define ifr_bandwidth ifr_ifru.ifru_ivalue /* link bandwidth */ # define ifr_qlen ifr_ifru.ifru_ivalue /* queue length */ # define ifr_newname ifr_ifru.ifru_newname /* New name */ # define _IOT_ifreq _IOT(_IOTS(char),IFNAMSIZ,_IOTS(char),16,0,0) # define _IOT_ifreq_short _IOT(_IOTS(char),IFNAMSIZ,_IOTS(short),1,0,0) # define _IOT_ifreq_int _IOT(_IOTS(char),IFNAMSIZ,_IOTS(int),1,0,0) DE>
 
 
DE> /* Structure used in SIOCGIFCONF request. Used to retrieve interface    configuration for machine (useful for programs which must know all    networks accessible). */ struct ifconf   {     int ifc_len; /* Size of buffer. */     union       {         __caddr_t ifcu_buf;         struct ifreq *ifcu_req;       } ifc_ifcu;   }; # define ifc_buf ifc_ifcu.ifcu_buf /* Buffer address. */ # define ifc_req ifc_ifcu.ifcu_req /* Array of structures. */ # define _IOT_ifconf _IOT(_IOTS(struct ifconf),1,0,0,0,0) /* not right */DE>

좋은 웹페이지 즐겨찾기