c - 如何获取网络设备统计信息?

标签 c linux linux-kernel network-programming posix

我尝试了一些例子。部分适用于旧的 linux-api,部分不编译,部分取决于内核版本。

我需要通过名称在设备上传输和接收字节。

尝试这个,但不知道如何设置默认命名空间或 init_net:

#include <linux/netdevice.h>
struct net_device *dev;
dev = (struct net_device*) dev_get_by_name(&init_net,"eth0");

是否可以从 posix sockets 而不是 netdevice 获取统计数据?

最佳答案

有更简单的方法。复制自 http://man7.org/linux/man-pages/man3/getifaddrs.3.html

版本顶部

   The getifaddrs() function first appeared in glibc 2.3, but before
   glibc 2.3.3, the implementation supported only IPv4 addresses; IPv6
   support was added in glibc 2.3.3.  Support of address families other
   than IPv4 is available only on kernels that support netlink.

 #include <arpa/inet.h>
   #include <sys/socket.h>
   #include <netdb.h>
   #include <ifaddrs.h>
   #include <stdio.h>
   #include <stdlib.h>
   #include <unistd.h>
   #include <linux/if_link.h>

   int main(int argc, char *argv[])
   {
       struct ifaddrs *ifaddr, *ifa;
       int family, s, n;
       char host[NI_MAXHOST];

       if (getifaddrs(&ifaddr) == -1) {
           perror("getifaddrs");
           exit(EXIT_FAILURE);
       }

       /* Walk through linked list, maintaining head pointer so we
          can free list later */

       for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) {
           if (ifa->ifa_addr == NULL)
               continue;

           family = ifa->ifa_addr->sa_family;

           /* Display interface name and family (including symbolic
              form of the latter for the common families) */

           printf("%-8s %s (%d)\n",
                  ifa->ifa_name,
                  (family == AF_PACKET) ? "AF_PACKET" :
                  (family == AF_INET) ? "AF_INET" :
                  (family == AF_INET6) ? "AF_INET6" : "???",
                  family);

           /* For an AF_INET* interface address, display the address */

           if (family == AF_INET || family == AF_INET6) {
               s = getnameinfo(ifa->ifa_addr,
                       (family == AF_INET) ? sizeof(struct sockaddr_in) :
                                             sizeof(struct sockaddr_in6),
                       host, NI_MAXHOST,
                       NULL, 0, NI_NUMERICHOST);
               if (s != 0) {
                   printf("getnameinfo() failed: %s\n", gai_strerror(s));
                   exit(EXIT_FAILURE);
               }

               printf("\t\taddress: <%s>\n", host);

           } else if (family == AF_PACKET && ifa->ifa_data != NULL) {
               struct rtnl_link_stats *stats = (struct rtnl_link_stats *)ifa->ifa_data;

               printf("\t\ttx_packets = %10u; rx_packets = %10u\n"
                      "\t\ttx_bytes   = %10u; rx_bytes   = %10u\n",
                      stats->tx_packets, stats->rx_packets,
                      stats->tx_bytes, stats->rx_bytes);
           }
       }

       freeifaddrs(ifaddr);
       exit(EXIT_SUCCESS);
   }

关于c - 如何获取网络设备统计信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37099016/

相关文章:

linux - 匹配 if 条件中的字符串

linux - 如何在 Intel Galileo 上重置运行代码

linux - 自动化 Amazon EBS 快照 任何人在 linux 上都有一个好的脚本或解决方案

c - linux proc大小限制问题

C linux : parent process not blocking 中子进程和父进程之间的通信

C-编译错误

c++ - 我应该如何为 c 字符串 char 数组分配内存?

c - 如何在c中打印程序编译位置的路径

linux - 程序栈的增长方向到底是什么?

c - 如何在内核模块中获取数组的地址,以便我能够在用户空间应用程序中使用它?