我已经搜索了一段时间,但没有明确的关键字来找到相同的问题。
简要说明我的问题:
ifconfig
仅显示启用的 NIC。
# ifconfig
br0 Link encap:Ethernet HWaddr XX:XX:XX:XX:XX:XX
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
...
eth0 Link encap:Ethernet HWaddr XX:XX:XX:XX:XX:XX
inet addr:XX.XX.XX.XX Bcast:XX.XX.XX.XX Mask:XX.XX.XX.XX
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
...
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:16436 Metric:1
...
但ip addr
显示所有 NIC。
# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> ... UNKNOWN
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> ... state UP
3: eth1: <BROADCAST,MULTICAST> ... state DOWN
8: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> ... state UNKNOWN
根据屏幕输出,我知道ifconfig
通过字符串知道网卡是否启用向上。 (例如环回,向上,LOWER_UP)
据我所知,该字符串与硬件无关。因此,这两者都不/sys/class/net/NIC/operstate
是/sys/class/net/NIC/carrier
答案。
我的问题是:那根绳子从哪里来?
(我猜它包含在文件系统的某个文件中。)
答案1
man ifconfig
说:
ifconfig 用于配置内核驻留网络接口。它在启动时用于根据需要设置接口。之后,通常只有在调试或需要系统调整时才需要它。
如果未给出参数,ifconfig 将显示当前活动接口的状态。
如果给出单个接口参数,则仅显示给定接口的状态;
如果给出单个 -a 参数,它将显示所有接口的状态,甚至包括那些已关闭的接口。
否则,它会配置一个接口。
man netdevice
也可以分享一些关于这个问题的线索。它使用 ioctl() 系统调用。
另一种技术是使用strace
.
它为您提供了您传递给它的任何程序所进行的所有系统调用的列表,以及它们的参数和返回值。如果您的程序只是转储一些信息并退出,而不是长时间运行,那么只需对您看到的所有系统调用执行一个 man 即可非常简单,这些系统调用看起来可能会提供您正在搜索的信息。
当我跑步时
strace ifconfig
一些有趣的调用是:
open("/proc/net/dev", O_RDONLY) = 6
接下来是一堆 ioctl:
ioctl(5, SIOCGIFFLAGS, {ifr_name="eth0", ifr_flags=IFF_UP|IFF_BROADCAST|IFF_RUNNING|IFF_MULTICAST}) = 0
ioctl(5, SIOCGIFHWADDR, {ifr_name="eth0", ifr_hwaddr=12:cd:4b:bb:7f:39}) = 0
ioctl(5, SIOCGIFMETRIC, {ifr_name="eth0", ifr_metric=0}) = 0
ioctl(5, SIOCGIFMTU, {ifr_name="eth0", ifr_mtu=9001}) = 0
答案2
感谢malyy的帮助。这是我的测试代码。
check_ifup.c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
int main(int argc, char* argv[])
{
if (argc < 2)
{
printf("Usage: ./check_ifup interface_name\n");
return 0;
}
struct ifreq ifr;
int sockfd;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
bzero(&ifr, sizeof(ifr));
strcpy(ifr.ifr_name, argv[1]);
ioctl(sockfd, SIOCGIFFLAGS, &ifr);
if (ifr.ifr_flags & IFF_UP)
printf("%s is up\n", argv[1]);
else
printf("%s is down or unknown\n", argv[1]);
close(sockfd);
return 0
}
参考: