2013-05-02 249 views
2

我正在編寫一個程序,它可以讀取我已經在特定網絡接口(VLAN:eth0.32)上分配的IP地址。我不知道我是否已經分配了IPv4或IPv6地址,因此我試圖將其寫入協議族不可知論者。創建與IPv4和IPv6兼容的套接字

它的工作方式是:使用for,我瀏覽可用網絡接口列表,然後停下來找到我的VLAN(eth0.32)讀取IP地址的位置。無論如何,在這個開發過程中,我只是希望它適用於IPv4,但是當我想要實現IPv6支持時,請準備好。

的程序工作,如果我通常創建套接字讀取IPv4地址:

sd=socket(PF_INET, SOCK_DGRAM, 0); 

但是,當我將無法讀取IPv6的這個插座系列(PF_INET = IPv4)的我做它解決像這樣:

sd=socket(PF_INET6, SOCK_DGRAM, 0); 
setsockopt(sd, SOL_SOCKET, IPV6_V6ONLY, 0, sizeof(int)); 

的問題是,這個IPv6套接字,它未能完成,如果條件讀取IP地址:

if (ioctl(sd, SIOCGIFCONF, &ifc) == 0) 

欲瞭解更多信息,這是我的整個代碼:

#include <stdio.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <sys/ioctl.h> 
#include <netinet/in.h> 
#include <netdb.h> 
#include <net/if.h> 

int main(int argc, char **argv) 
{ 

    struct ifconf ifc; 
    struct ifreq ifr[MAX_NETWORK_INTERFACES]; 
    int ifc_num, addr, i; 
    static uint8 sd=0; 

    sd=socket(PF_INET6, SOCK_DGRAM, 0); 
    setsockopt(sd, SOL_SOCKET, IPV6_V6ONLY, 0, sizeof(int)); //I change the socket option IPV6_V6ONLY to false, so it should be compatible with IPv4 

    if (sd > 0) 
    { 
     ifc.ifc_len = sizeof(ifr); 
     ifc.ifc_ifcu.ifcu_buf = (caddr_t)ifr; //Buffer address 

     if (ioctl(sd, SIOCGIFCONF, &ifc) == 0) 
     { 
      ifc_num = ifc.ifc_len/sizeof(struct ifreq); //Number of network interfaces found 

      for (i = 0; i < ifc_num; i++) 
      { 

       if(ifr[i].ifr_addr.sa_family != AF_INET) //If it is not an IPv4 address, we do nothing 
       { 
        continue; 
       } 

       if (strcmp(ifr[i].ifr_ifrn.ifrn_name,"eth0.32")==0) 
       { 
        if (ioctl(sd, SIOCGIFADDR, &ifr[i]) == 0) // HERE IS WHERE THE IPv6 SOCKET DOESN'T ENTER!!! 
        { 
         addr = ntohl(((struct sockaddr_in *)(&ifr[i].ifr_addr))->sin_addr.s_addr); 

        } 

        fclose(fp); 

        break; // end loop 
       } 
      } 
     } 
    } 
    return addr; 

} 

預先感謝您的幫助!

+0

GetSocketForAddressForAdapter可能會幫助你 - https://github.com/jselbie/stunserver/blob/master/networkutils/adapters.cpp#L111 – selbie 2013-05-03 09:38:40

回答

0

您應該使用​​而不是ioctl SIOCGIFADDR

+0

在這種情況下,是'(ioctl(sd,SIOCGIFCONF,&ifc)== 0 )'也不行? – Nacao 2013-05-03 07:55:33

+0

@Nacao,這些IOCTls沒有被任何標準覆蓋,也不便攜。您必須諮詢您的操作系統文檔 - 或者如果對此提出問題,請告訴我們您正在使用的操作系統。在Linux上使用'rnetlink(7)'。在Windows上,您可能需要「IP幫助程序」API http://msdn.microsoft.com/en-us/library/windows/desktop/aa366071(v=vs.85).aspx – Ben 2013-05-03 09:38:13

+0

感謝您的快速解答。我正在使用Linux。我已經測試了這個代碼實現僅適用於IPv4地址,並且它工作正常,上面描述的問題出現在我想添加IPv6支持時,它不再適用於IPv4。 – Nacao 2013-05-03 09:46:57