• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    AIX V5.3 中 IPv4 和 IPv6 的網絡接口操作

    發布: 2007-6-13 20:58 | 作者: ibmdw | 來源: 網絡轉載 | 查看: 28次 | 進入軟件測試論壇討論

    領測軟件測試網
    了解更多關于套接字 I/O 控制 (ioctl) 命令的內容,以及如何使用它們完成各種網絡相關的操作.操作系統為套接字、路由表、ARP 表、全局網絡參數和接口提供了相應的控制操作方式。本文適用于對 Internet Protocol Version 4 (IPv4) 和 Internet Protocol Version 6 (IPv6) 堆棧網絡級操作感興趣的 AIX® Version 5.3 開發人員。

    引言

    文件描述符是低層的輸入和輸出接口。描述符可以表示到設備、管道或套接字的連接,這些連接用于與另一個進程或普通文件進行通信。I/O 控制 (ioctl) 函數調用可以用來對特殊文件的基礎設備參數進行操作。它們可以完成與打開的文件描述符相關聯的控制功能。這些命令涉及文件、流、普通數據鏈路控制以及其他各種設備。

    本文將討論 AIX® Version 5.3 中提供的與網絡操作和套接字相關的命令。在下列文件中列出了與套接字相關的命令和結構:

    • sys/ioctl.h
    • net/if_arp.h
    • net/if.h
    • net/netopt.h
    • netinet/in.h
    應用程序開發人員可以使用這些命令,并且在 AIX Version 5.3 的文檔中對這些命令進行了詳細的描述。本文說明了有關 Internet Protocol Version 6 (IPv6) 地址和 Internet Protocol Version 4 (IPv4) 堆棧的常用命令的典型用法。

    使用 ioctl 套接字控制選項

    通常,網絡程序需要了解系統中所有有關網絡接口和 IP 地址的可用信息,F在,未來的應用程序可以支持 IPv4 和 IPv6 雙協議棧。ioctl 結構需要對指針進行遍歷和操作,以處理 IPv4 和 IPv6 地址在長度上的差別(除了使用合適的套接字結構 sockaddr_in6 或 sockaddr_storage 之外)。

    AIX Version 5.3 提供了很多 ioctl 套接字控制選項,以提取各種有關網絡接口的信息。這些 ioctl 命令用于查詢接口的狀態并對其屬性進行操作。下面的部分中包含了一些有用的命令的代碼段。有關 ioctl 命令的完整列表,請參見參考資料部分。

    ioctl 命令所使用的結構

    下面的清單介紹了一些最重要的結構,使用 ioctl 套接字命令時常常用到這些結構。


    清單 1. struct ifreq (/usr/include/net/if.h)
    				
    /* 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 {
    #ifndef IFNAMSIZ
    #define IFNAMSIZ        16
    #endif
            char    ifr_name[IFNAMSIZ]; 
            union {
                    struct  sockaddr ifru_addr;
                    struct  sockaddr ifru_dstaddr;
                    struct  sockaddr ifru_broadaddr;
                    __ulong32_t     ifru_flags;
                    int     ifru_metric;
                    caddr_t ifru_data;
                    u_short ifru_site6;
                    __ulong32_t   ifru_mtu;
                    int     ifru_baudrate;
            } ifr_ifru;
    
    Following macros are provided for convenience
    
    #define ifr_addr        ifr_ifru.ifru_addr      /* address */
    #define ifr_dstaddr     ifr_ifru.ifru_dstaddr   /* other end of p-to-p link */
    #define ifr_broadaddr   ifr_ifru.ifru_broadaddr /* broadcast address */
    #define ifr_flags       ifr_ifru.ifru_flags     /* flags */
    #define ifr_metric      ifr_ifru.ifru_metric    /* metric */
    #define ifr_data        ifr_ifru.ifru_data      /* for use by interface */
    #define ifr_site6       ifr_ifru.ifru_site6     /* IPv6 site index */
    #define ifr_mtu         ifr_ifru.ifru_mtu       /* mtu of interface */
    #define ifr_isno        ifr_ifru.ifru_data      /* pointer to if_netopts */
    #define ifr_baudrate    ifr_ifru.ifru_baudrate  /* baudrate of interface */
    };
          


    清單 2. struct ifconf (/usr/include/net/if.h)
    				
    /*
     * 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 associated buffer */
            union {
                    caddr_t ifcu_buf;
                    struct  ifreq *ifcu_req;
            } ifc_ifcu;
    
    Following macros are provided for convenience
    
    #define ifc_buf ifc_ifcu.ifcu_buf       /* buffer address */
    #define ifc_req ifc_ifcu.ifcu_req       /* array of structures returned */
    };
          





    回頁首


    代碼示例

    下面的表 1 介紹了一些接口檢索命令。該信息來源于 IBM System p™ 和 AIX。


    表 1. 接口檢索命令
    ioctl 命令 描述
    SIOCGSIZIFCONF 獲得獲取 SIOCGIFCONF 返回的所有接口的配置信息所需的內存。
    		
    ioctl(fd, SIOCGSIZIFCONF, (caddr_t)&ifconfsize);
    int ifconfsize;

    SIOCGIFADDR

    SIOCSIFADDR
    SIOCGIFADDR 獲取接口地址,而 SIOCSIFADDR 設置接口地址。ifr.ifr_addr 字段返回地址。
    ioctl(fd, SIOCGIFADDR, (caddr_t)&ifr, sizeof(struct ifreq));
    ioctl(fd, SIOCSIFADDR, (caddr_t)&ifr, sizeof(struct ifreq));
    struct ifreq ifr;

    SIOCGIFCONF 返回系統中配置的所有接口的配置信息。
    ioctl(fd, SIOCGIFCONF, (caddr_t)&ifc);
    struct ifconf ifconf;

    SIOCGSIZIFCONF

    下面的代碼段可以獲取用來填充所有配置接口的信息所需的緩沖區大小。


    清單 3. 使用 SIOCGSIZIFCONF 獲得所需的緩沖區大小
    				
    /*Function to get the size needed to allocate for buffers*/
    int get_interface_size(int sd){
        int ret,size;
        ret=ioctl(sd,SIOCGSIZIFCONF,&size);
        if(ret==-1){
           perror("Error getting size of interface :");
           return ret;
        }
        return size;
    }
    
    main
    {
        struct ifconf ifc;
        int sd;
        sd=socket(AF_INET6,SOCK_DGRAM,0);
        printf("Size of memory needed = %d\n",get_interface_size(sd));
    }
     
          

    上面代碼的輸出是:

    $> ./myprog
    Size of memory needed = 628
          

    SIOCGIFCONF 和 SIOCGIFADDR

    SIOCGIFCONF 和 SIOCGIFADDR 命令可以用來檢索接口的地址。SIOCGIFCONF 可以用來獲取所有配置接口的信息,SIOCGIFADDR 可以用來檢索特定接口的地址。


    清單 4. 使用 SIOCGIFCONF 獲取配置信息

    					
    /*This function uses loops to find out buffer size instead of SIOCGSIZIFCONF 
      allocates the buffer and gets the information list*/
    int alloc_buffer_size(int sd,struct ifconf *ifc){
        int ret=-1,bsz=sizeof(struct ifreq);
        int prevsz=bsz;
        ifc->ifc_req=NULL;
        ifc->ifc_len=bsz;
        do{
           ifc->ifc_req=(struct ifreq *)realloc(ifc->ifc_req,bsz);
           if(!ifc->ifc_req){
             perror("Malloc failed :");
             return ret;
           }
           ifc->ifc_len=bsz;
           ret=ioctl(sd,SIOCGIFCONF,(caddr_t)ifc);
           if(ret==-1){
              perror("Error getting size of interface :");
              return ret;
           }
          if(prevsz==ifc->ifc_len)
            break;
          else{
             bsz*=2;
             prevsz=(0==ifc->ifc_len ? bsz : ifc->ifc_len) ;
          }
        }while(1);
        ifc->ifc_req=(struct ifreq *)realloc(ifc->ifc_req,prevsz);
        return ifc->ifc_len;
    }
    
          

    在使用 ifreq 結構中的配置信息填充了列表之后,可以對其進行遍歷以檢索所需的數據。根據調用之后該結構中填充的套接字地址的長度,可以對這個指針進行移動。下面的清單 5 顯示了上面代碼的列表中獲得的系統中可用的 IP。


    清單 5. 從配置列表中檢索信息
    					
    #define MAX(x,y) ((x) > (y) ? (x) : (y))
    #define SIZE(p) MAX((p).sa_len, sizeof(p))
    
    /* This function prints all the configured IPs on the
     * system given the ifconf structure allocated previously*/
    void print_ips(struct ifconf *ifc){
         char *cp,*cplim,addr[INET6_ADDRSTRLEN];
         struct ifreq *ifr=ifc->ifc_req;
         cp=(char *)ifc->ifc_req;
         cplim=cp+ifc->ifc_len;
         for(;cp<cplim;cp+=(sizeof(ifr->ifr_name) + SIZE(ifr->ifr_addr))){
            /* NOTE: You cannot just increment cp with sizeof(struct ifreq)
             * as structures returned are of different length.
             */
            ifr=(struct ifreq *)cp;
            printf("%s :",ifr->ifr_name);
            getip(ifr,addr);
            printf("%s\n",addr);
         }
          return ;
    }
    main
    {
        struct ifconf ifc;
        int sd;
        sd=socket(AF_INET6,SOCK_DGRAM,0);
        alloc_buffer_size(sd,&ifc);
        print_ips(&ifc);
    }
          

    上面代碼的輸出是:

    $> ./myprog
    en0 :6.3.6.0
    en0 :9.182.192.169
    en0 :fe80::209:6bff:feeb:70b2
    sit0 :1.4.4.0
    sit0 :::9.182.192.169
    lo0 :24.3.0.0
    lo0 :127.0.0.1
    lo0 :::1
          


    清單 6. 使用 SIOCGIFADDR 獲取接口地址
    					
    /* Given a ifreq structure this function returns its IP address */
    void getip(struct ifreq *ifr,char *addr){
      struct sockaddr *sa;
      sa=(struct sockaddr *)&(ifr->ifr_addr);
      switch(sa->sa_family){
        case AF_INET6:
          inet_ntop(AF_INET6,(struct in6_addr *)&(((struct sockaddr_in6 *)sa)->sin6_addr),
             addr,INET6_ADDRSTRLEN);
          break;
        default : strcpy(addr,inet_ntoa(((struct sockaddr_in *)sa)->sin_addr));
        }
       return;
    }
    
    main
    {
      char netaddr[INET_ADDRSTRLEN];
      int sd;
      sd=socket(AF_INET,SOCK_DGRAM,0);
      strcpy(ifr.ifr_name,"en0");
      if((ioctl(sd,SIOCGIFADDR,(caddr_t)&ifr,sizeof(struct ifreq)))<0)
         perror("Error : ");
      getip(&ifr,netaddr);
      printf("%s\n",netaddr);
    }
          

    上面代碼的輸出是:

    $./myprog
    9.182.192.35
          

    下面的表 2 介紹了接口標志和一些屬性檢索命令。


    表 2. 接口標志和屬性檢索命令
    ioctl 命令 描述
    SIOCGIFFLAGS

    SIOCSIFFLAGS
    SIOCGIFFLAGS 可以獲取接口標志。

    SIOCSIFFLAGS 可以設置接口標志。

    ioctl(fd, cmd, (caddr_t)&ifr);
    struct ifreq ifr;

    SIOCGIFFLAGS

    在使用 SIOCGIFCONF 獲取了接口列表之后,您可以使用 SIOCGIFFLAGS-SIOCSIFFLAGS 對來獲取和設置接口的屬性。接口標志表示為 IFF_XXX。有關完整的列表,請參閱文件 /usr/include/net/if.h。

    下面的示例使用一對接口標志來檢索其當前狀態,并檢查環回。也可以使用其他選項。


    清單 7. 驗證接口的狀態和類型
    				
       for(;cp<cplim;){
            ifr=(struct ifreq *)cp;
            cp+=(sizeof(ifr->ifr_name) + SIZE(ifr->ifr_addr));
            printf("%-9s  ",ifr->ifr_name);
            ret=ioctl(sd,SIOCGIFFLAGS,(caddr_t)ifr);
            if(ret==-1){
              perror("Error getting flags for interface :");
              return ;
            }
            if((ifr->ifr_flags)&IFF_UP)
               printf("UP");
            else printf("DOWN");
            if((ifr->ifr_flags)&IFF_LOOPBACK)
               printf(",Loopback");
    	printf("\n");
         }
          

    上面代碼的輸出是:

    $> ./myprog
    en0        UP
    en0        UP
    en0        UP
    sit0       UP
    sit0       UP
    lo0        UP,Loopback
    lo0        UP,Loopback
    lo0        UP,Loopback
          


    清單 8. 設置接口標志
    				
    	Partial output of ifconfig before setting the flag
    
    sit0: flags=4900041<UP,RUNNING,LINK0,64BIT>
            inet6 ::9.182.192.169/96
    
    Code to set the interface flag 
    
    int set_interface_flag(int sd,short flag,char *interface){
        struct ifreq ifr;
        int oldflags;
        strcpy(ifr.ifr_name,interface);
        if((ioctl(sd,SIOCGIFFLAGS,(caddr_t)&ifr))==-1){
          perror("Error getting interface flags :");
          return -1;
        }
        printf("Setting new interface flag 0X%x\n",flag);
        ifr.ifr_flags|=flag;
        if((ioctl(sd,SIOCSIFFLAGS,(caddr_t)&ifr))==-1){
          perror("Error setting interface flags :");
          return -1;
        }
        return 0;
    }
    
    main
    {
        int sd;
        sd=socket(AF_INET6,SOCK_DGRAM,0);
        set_interface_flag(sd,IFF_NOTRAILERS,"sit0");
    }
    

    上面代碼的輸出是:

    You must have permission to change the flag
    
    $./myprog
    Setting new interface flag 0X20
    
    $ifconfig -a
    .............
    .............
    sit0: flags=4900061<UP,NOTRAILERS,RUNNING,LINK0,64BIT>
            inet6 ::9.182.192.169/96
    .............
    .............
          

    表 3 介紹了一些用于網絡優化的命令。


    表 3. 用于網絡優化的命令
    ioctl 命令 描述
    SIOCGIFMTU SIOCGIFMTU 可以獲取接口的最大傳輸單元 (MTU)。

    ioctl(fd, cmd, (caddr_t)&ifr);
    struct ifreq ifr;

    這個 MTU 值存儲在 ifr.ifr_mtu 字段中。

    SIOCGNETOPT
    SIOCGNETOPT1
    SIOCGNETOPT 可以獲取一個網絡選項的值。

    ioctl(fd, cmd, (caddr_t)&oreq);
    struct optreq oreq;

    SIOCGNETOPT1 可以獲取當前值、缺省值和網絡選項的范圍。

    ioctl(fd, SIOCGNETOPT1, (caddr_t)&oreq);
    struct optreq1 oreq;

    SIOCGIFMTU


    清單 9. 從 ifreq 結構獲取 MTU
    				
            ret=ioctl(sd,SIOCGIFMTU,ifr);
            if(ret==-1){
              perror("Error getting mtu for interface :");
              return ;
            }
            printf("  %d\n",ifr->ifr_mtu);
          

    SIOCGNETOPT1

    SIOCGNETOPT1 給出當前值、缺省值和網絡選項的范圍。


    清單 10. 從 optreq1 結構獲取網絡選項
    				
    /*Function to get the network options*/
    int print_network_options(int sd){
        int ret;
        struct optreq1 oreq;
        oreq.getnext=1;
        while((ioctl(sd,SIOCGNETOPT1,(caddr_t)&oreq))!=-1)
        printf("%s = %s\n",oreq.name,oreq.data);
       return 0;
    }
          

    上面代碼的輸出是:

    $> ./myprog
    arpqsize = 12
    arpt_killc = 20
    arptab_bsiz = 7
    arptab_nb = 149
    ........
    ........
    ........
    ........
    ifsize = 256
    inet_stack_size = 16
    ip6_defttl = 64
    ........
          

    在 AIX 中,您還可以使用 no 命令來管理各種網絡優化參數。有關更詳細的信息,請參閱相應的 man 頁面。


    清單 11. AIX 計算機上“no”命令的輸出
    				
    $> no -a|more
                   arpqsize = 12
                   arpt_killc = 20
                  arptab_bsiz = 7
                    arptab_nb = 149
                    bcastping = 0
          clean_partial_conns = 0
                     delayack = 0
                delayackports = {}
             dgd_packets_lost = 3
                dgd_ping_time = 5
               dgd_retry_time = 5
           directed_broadcast = 0
             extendednetstats = 0
                     fasttimo = 200
    ........
    ........
          





    回頁首


    總結

    ioctl 命令的功能非常強大,您可以使用它們來訪問或修改網絡(或其他)設備的可配置參數。它們使用了各種各樣的數據結構,應該使用正確的數據來填充這些數據結構,以便實現預期的結果。您將發現在使用 AF_INET 和 AF_INET6 系列時存在的區別。本文提供了一小部分常用命令子集的代碼示例。要獲得 AIX Version 5.3 中完整的命令清單,請轉到參考資料部分。我們希望這些關于 ioctl 的信息對您有用。

     

    延伸閱讀

    文章來源于領測軟件測試網 http://www.kjueaiud.com/

    TAG: aix


    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備10010545號-5
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>