在Linux中通过SIOCGIFCONF轮询接口名称

我正在尝试轮询networking设备名称。 我已经从各种片段拼凑起来了,

  1. http://unixhelp.ed.ac.uk/CGI/man-cgi?netdevice+7
  2. http://lists.apple.com/archives/Unix-porting/2002/Apr/msg00134.html
  3. http://ubuntuforums.org/showthread.php?t=1421487

但是我的输出只是乱码。

#include <stdio.h> #include <stdlib.h> #include <net/route.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <net/if.h> #define BUFLEN 1024 #define SEQ 9999 int main (int argc, const char* argv[]) { // File descriptor for socket int socketfd; struct ifconf conf; struct ifreq req[10]; struct ifreq *ifr; printf("Opening socket..."); socketfd = socket(AF_ROUTE, SOCK_RAW, 0); if (socketfd >= 0) { printf(" OK\n"); conf.ifc_len = sizeof(req); conf.ifc_buf = (__caddr_t) req; ioctl(socketfd,SIOCGIFCONF,&conf); printf("Discovering interfaces...\n"); int i; for (i=0; i<conf.ifc_len/sizeof(req[0]); i++) { ifr = &conf.ifc_req[i]; printf("%d. %s\n", i+1, req[i].ifr_name); } } else { printf("Failed!\n"); } return 0; } 

输出:

 Opening socket... OK Discovering interfaces... ?u???}??Gh??? 2. p?9}? 3. 4. v?=?n??u?`?y??]g?<?~?v?? 5. 6. 7. 8. ?v?T? 9. ?|?mw??j??v??h??|??v?T00~??v?$?|??|?@ 10. T00~??v?$?|??|?@ 

我试着逐个输出ifr_name数组的每个字符,以查看它们是否被终止,但是没有太大改变。 我的程序每次迭代都输出不同的东西,所以这导致我认为我引用了错误的东西。 有人能提供一些见解,我可能做错了什么?

请参阅http://git.netfilter.org/cgi-bin/gitweb.cgi?p=libmnl.git;a=blob;f=examples/rtnl/rtnl-link-dump.c;hb=HEAD关于如何获取Linux上的接口列表&#x3002; AF_ROUTE是一些BSD的东西,因为其明显的局限性(例如在一个接口上传递多个地址),在Linux上不鼓励使用ioctl。

以下是我为Mac OS X整理的一些代码:

 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <net/if.h> #include <arpa/inet.h> #include <netinet/in.h> /* This is defined on Mac OS X */ #ifndef _SIZEOF_ADDR_IFREQ #define _SIZEOF_ADDR_IFREQ sizeof #endif int main (int argc, const char* argv[]) { // File descriptor for socket int socketfd; struct ifconf conf; char data[4096]; struct ifreq *ifr; char addrbuf[1024]; int i; printf("Opening socket..."); socketfd = socket(AF_INET, SOCK_DGRAM, 0); if (socketfd >= 0) { printf(" OK\n"); conf.ifc_len = sizeof(data); conf.ifc_buf = (caddr_t) data; if (ioctl(socketfd,SIOCGIFCONF,&conf) < 0) { perror("ioctl"); } printf("Discovering interfaces...\n"); i = 0; ifr = (struct ifreq*)data; while ((char*)ifr < data+conf.ifc_len) { switch (ifr->ifr_addr.sa_family) { case AF_INET: ++i; printf("%d. %s : %s\n", i, ifr->ifr_name, inet_ntop(ifr->ifr_addr.sa_family, &((struct sockaddr_in*)&ifr->ifr_addr)->sin_addr, addrbuf, sizeof(addrbuf))); break; #if 0 case AF_INET6: ++i; printf("%d. %s : %s\n", i, ifr->ifr_name, inet_ntop(ifr->ifr_addr.sa_family, &((struct sockaddr_in6*)&ifr->ifr_addr)->sin6_addr, addrbuf, sizeof(addrbuf))); break; #endif } ifr = (struct ifreq*)((char*)ifr +_SIZEOF_ADDR_IFREQ(*ifr)); } close(socketfd); } else { printf(" Failed!\n"); } return 0; } 

如果您希望在您添加或删除接口时收到投票通知。 或者像你一样只是想从系统中找出接口名称? 如果是后者,请看getifaddrs() 。