2012-04-16 62 views
0

有非常有用的功能調用​​,它檢索所有machin網絡地址。問題是我使用的舊版glibc版本沒有這個功能。有沒有更換它?我正在查找並找到getipnodebyname,但當地址未映射到/ etc/hosts文件中時,它是無用的。類似於舊glibc版本上的getifaddrs

+0

你正在使用哪個版本的glibc – 2012-04-16 11:56:14

+0

考慮到這個實現是在開源的glibc中的,你可以把這個實現併入你的代碼中(假設它也是與這種方法兼容的許可證) 。 請注意,glibc 2.3在2002年發佈了' – Petesh 2012-04-16 12:57:10

回答

2

要添加到上一個答案,這裏是SIOCGIFCONF -approach的示例。你必須這樣做:

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

int fd; 

int get_iface_list(struct ifconf *ifconf) 
{ 
    int rval; 
    if((rval = ioctl(fd, SIOCGIFCONF , (char*) ifconf )) < 0) 
     perror("ioctl(SIOGIFCONF)"); 

    return rval; 
} 

int main() 
{ 
    static struct ifreq ifreqs[100]; 
    static struct ifconf ifc; 
    char *ptr; 

    fd = socket(AF_INET, SOCK_DGRAM, 0); 
    if (fd < 0) 
     return 1; 

    ifc.ifc_buf = (char*) (ifreqs); 
    ifc.ifc_len = sizeof(ifreqs); 

    if(get_iface_list(&ifc) < 0) return -1; 

    /* Go through the list of interfaces */ 
    for (ptr = ifc.ifc_buf; ptr < ifc.ifc_buf + ifc.ifc_len;) 
    { 
     struct ifreq *ifr = (struct ifreq*)ptr; 
     int len = (sizeof(struct sockaddr) > ifr->ifr_addr.sa_len) ? 
       sizeof(struct sockaddr) : ifr->ifr_addr.sa_len; 

     ptr += sizeof(ifr->ifr_name) + len; 

      /* Do what you need with the ifr-structure. 
      * ifr->ifr_addr contains either sockaddr_dl, 
      * sockaddr_in or sockaddr_in6 depending on 
      * what addresses and L2 protocols the interface 
      * has associated in it. 
      */ 
    } 

    close(fd); 
    return 0; 
} 

當然有一些陷阱。根據Unix網絡編程第17.6章ioctl(fd, SIOCGIFCONF, array)可能不會在某些平臺上返回錯誤,如果參數指向的數組太小。數據將被連接起來。解決此問題的唯一方法是在循環中調用ioctl(),直到獲得相同的結果長度兩次,同時增加數組的大小。當然,因爲這是2012年,我不確定這是多麼相關。

ifreqs數組的大小純粹是在這種情況下的猜測。請記住,陣列將爲每個與接口關聯的L2和L3地址包含一個struct ifreq。例如,假設您也有IPv6地址,對於lo-interface,您將獲得三個條目:以太網,IPv4和IPv6。因此要預留足夠的空間或應用kludge。

要獲得廣播地址和其他附加信息,您需要在循環中調用其他ioctl()調用。當然,所有可能的選項取決於您的操作系統提供的內容。

欲瞭解更多信息,我建議閱讀W.理查德史蒂文斯的Unix網絡編程。這是關於這個主題最綜合的書。

+0

謝謝!這正是我需要的。 – gumik 2012-04-17 12:25:40

2

執行等效操作的傳統方法是使用SIOCGIFCONF操作到ioctl。任何套接字都可以用於操作。它不像單個函數調用那麼簡單。

+1

調用'SIOCGIFCONF'獲取接口列表後,您可以調用每個接口的SIOCGIFFLAGS' ioctl以查看它是否已啓動;如果是,則調用「SIOCGIFADDR」ioctl來實際獲取地址。 – caf 2012-04-16 13:51:58