在 Linux 中通过 SIOCGIFCONF 轮询接口名称
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4937529/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Polling interface names via SIOCGIFCONF in Linux
提问by Parker
I'm attempting to poll networking device names. I've pieced this together from various snippets,
我正在尝试轮询网络设备名称。我从各种片段中拼凑起来,
- http://unixhelp.ed.ac.uk/CGI/man-cgi?netdevice+7
- http://lists.apple.com/archives/Unix-porting/2002/Apr/msg00134.html
- http://ubuntuforums.org/showthread.php?t=1421487
- http://unixhelp.ed.ac.uk/CGI/man-cgi?netdevice+7
- http://lists.apple.com/archives/Unix-porting/2002/Apr/msg00134.html
- http://ubuntuforums.org/showthread.php?t=1421487
But my output is just gibberish.
但我的输出只是胡言乱语。
#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;
}
Output:
输出:
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?$?|??|?@
I tried outputting each char of the ifr_name array one-by-one to see if they were null terminated but that didn't change much. Each iteration of my program outputs something different so this leads me to think I'm referencing something wrong. Can someone provide me some insight as to what I may be doing wrong?
我尝试逐一输出 ifr_name 数组的每个字符,以查看它们是否以空字符结尾,但这并没有太大变化。我的程序的每次迭代都会输出不同的东西,所以这让我认为我引用了错误的东西。有人可以让我了解我可能做错了什么吗?
采纳答案by user562374
Please see http://git.netfilter.org/cgi-bin/gitweb.cgi?p=libmnl.git;a=blob;f=examples/rtnl/rtnl-link-dump.c;hb=HEADon how to get the list of interfaces on Linux. AF_ROUTE is some BSD thing and the use of ioctl is discouraged on Linux for its apparent limitations (such as to convey multiple addresses on a single interface).
请参阅http://git.netfilter.org/cgi-bin/gitweb.cgi?p=libmnl.git;a=blob;f=examples/rtnl/rtnl-link-dump.c;hb=HEAD了解如何获取 Linux 上的接口列表。AF_ROUTE 是一些 BSD 的东西,不鼓励在 Linux 上使用 ioctl,因为它有明显的局限性(例如在单个接口上传送多个地址)。
回答by Duck
Poll as in you want to be notified if an interface is added or removed? Or polled as in you just want to find out the interface names once from the system? If the latter, take a look at getifaddrs().
如果添加或删除接口,您希望收到通知吗?或者轮询您只是想从系统中找出一次接口名称?如果是后者,请查看getifaddrs()。
回答by Sam Lantinga
Here's some code I put together for Mac OS X:
这是我为 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;
}