我有一个 FreeBSD 11 系统,其中我得到以下ifconfig
命令的输出
# ifconfig lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384 options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6> inet6 ::1 prefixlen 128 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 inet 127.0.0.1 netmask 0xff000000 nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL> groups: lo xn0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 options=503<RXCSUM,TXCSUM,TSO4,LRO> ether 0e:c2:a2:36:c1:b4 inet 10.0.0.71 netmask 0xffffff00 broadcast 10.0.0.255 nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL> media: Ethernet manual status: active
这里有两个疑问:
- 为什么我没有像在旧版 FreeBSD / ubuntu 系统上那样获得 RX、TX 字节和数据包计数?我正在使用一个实用程序来解析此响应以获取网络使用情况,但失败了(无法修改,它是第三方二进制文件)。
- FreeBSD 11 有任何变化吗?因为它在旧版本中运行良好?我更感兴趣的是修复此问题或进行配置更改(如果这是由某个文件控制的),而不是更改我的监控方法(例如解析来自或其他命令的
.conf
响应)iftop
提前致谢 !
编辑
具体来说,该二进制文件中使用了一个 C 库来获取统计数据,但结果为零。我附上了一个示例代码,该代码也返回了 rx/tx 字节的零值,因为该信息不可用。它使用库getifaddrs
中的函数sys/sockets
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <ifaddrs.h>
struct if_data {
unsigned char ifi_type;
unsigned char ifi_physical;
unsigned char ifi_addrlen;
unsigned char ifi_hdrlen;
unsigned char ifi_recvquota;
unsigned char ifi_xmitquota;
unsigned long ifi_mtu;
unsigned long ifi_metric;
unsigned long ifi_baudrate;
unsigned long ifi_ipackets;
unsigned long ifi_ierrors;
unsigned long ifi_opackets;
unsigned long ifi_oerrors;
unsigned long ifi_collisions;
unsigned long ifi_ibytes;
unsigned long ifi_obytes;
unsigned long ifi_imcasts;
unsigned long ifi_omcasts;
unsigned long ifi_iqdrops;
unsigned long ifi_noproto;
unsigned long ifi_recvtiming;
unsigned long ifi_xmittiming;
struct timeval ifi_lastchange;
};
int main()
{
struct ifaddrs *ifap, *ifa;
struct if_data *ifadata = NULL;
char *dev_name;
if (getifaddrs(&ifap) < 0) {
printf ("returning for null");
return 1;
}
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
if (ifa->ifa_flags & 0x01) {
if ( ifa->ifa_addr->sa_family == AF_LINK) {
if (ifa->ifa_data) {
ifadata = (struct if_data *)ifa->ifa_data;
dev_name = ifa->ifa_name;
if (ifadata->ifi_ipackets == 0 && ifadata->ifi_opackets == 0)
{
printf("returning as zero for %s", dev_name);
continue;
}
printf("name=%s ipkts=%ld opkts=%ld\n", dev_name,
ifadata->ifi_ipackets, ifadata->ifi_opackets);
printf("%lu", ifadata->ifi_ibytes);
printf("%lu", ifadata->ifi_ipackets);
printf("%lu", ifadata->ifi_ierrors);
printf("%lu", ifadata->ifi_iqdrops);
printf("%lu", ifadata->ifi_imcasts);
printf("%lu", ifadata->ifi_obytes);
printf("%lu", ifadata->ifi_opackets);
printf("%lu", ifadata->ifi_oerrors);
}
}
}
}
freeifaddrs(ifap);
return 0;
}
答案1
为了回答你的问题,我应该说,据我所知,FreeBSD - 以及 macOS - 从未显示过RX/TX 数据包作为命令的输出ifconfig
。但是如果你说它在 7.x 和 8.x 中可用,我应该说至少在 10 和 11 中是不行的,也许我没有注意到 7.x 8.x 的时间。事实上,包括 RHEL 衍生产品(RHEL、Fedora、CentOS、Scientific 等)、基于 Debian 的操作系统(Ubuntu、Debian Jessie 等)和大多数其他发行版在内的 Linux 发行版都通过 显示 RX/TX 数据包ifconfig
,但 FreeBSD 和 macOS 却不是这样。许多 FreeBSD 的命令与 Linux 中的命令无关,其中许多命令只是以相同的方式调用,但实际上,在许多情况下表现不同。与此同时,你的命令struct if_data
看起来不太熟悉——也不正确——对我来说,我建议你看看<net/if.h>
。换句话说,删除你的if_data
并尝试包含准确的标题。
无论如何,要显示 FreeBSD 中的输入/输出字节数,您应该使用netstat
。以下命令在 FreeBSD 和 macOS 上均可正常工作:
netstat -idb [interface]
-i : interface
-d : show the number of dropped packets
-b : show the number of packets in and out
如果需要,您还可以使用 -B。它显示有关 bpf() 对等点的统计信息。这包括 bpf 设备匹配、丢弃和接收了多少个数据包,以及有关当前缓冲区大小和设备统计信息。
顺便说一句,对于监控网络流量,你还有另一个我强烈推荐的选项。你可以使用systat
该-ifstat
选项获取接口的流量吞吐量、峰值和总量:
systat -ifstat