ohmu
·
2026-10-15
1#include "netio.h"
2
3#include "common/debug.h"
4#include "common/netif.h"
5#include "common/mallocHelper.h"
6
7#include <errno.h>
8#include <net/if.h>
9#include <net/if_dl.h>
10#include <net/if_types.h>
11#include <net/route.h>
12#include <sys/sysctl.h>
13#include <sys/socket.h>
14
15const char* ffNetIOGetIoCounters(FFlist* result, FFNetIOOptions* options) {
16 uint32_t defaultRouteIfIndex = ffNetifGetDefaultRouteV4()->ifIndex;
17
18 size_t bufSize = 0;
19 if (sysctl((int[]) { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, (options->defaultRouteOnly ? (int) defaultRouteIfIndex : 0) }, 6, nullptr, &bufSize, 0, 0) < 0) {
20 FF_DEBUG("sysctl({ CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, ifIndex }, 6, nullptr, &bufSize, 0, 0) failed: %s", strerror(errno));
21 return "sysctl({ CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, ifIndex }, 6, nullptr, &bufSize, 0, 0) failed";
22 }
23
24 FF_AUTO_FREE struct if_msghdr* buf = (struct if_msghdr*) malloc(bufSize);
25 if (sysctl((int[]) { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, (options->defaultRouteOnly ? (int) defaultRouteIfIndex : 0) }, 6, buf, &bufSize, 0, 0) < 0) {
26 FF_DEBUG("sysctl({ CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, ifIndex }, 6, buf, &bufSize, 0, 0) failed: %s", strerror(errno));
27 return "sysctl({ CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, ifIndex }, 6, buf, &bufSize, 0, 0) failed";
28 }
29
30 for (struct if_msghdr* ifm = buf;
31 ifm < (struct if_msghdr*) ((uint8_t*) buf + bufSize);
32 ifm = (struct if_msghdr*) ((uint8_t*) ifm + ifm->ifm_msglen)) {
33 if (ifm->ifm_type != RTM_IFINFO || !(ifm->ifm_flags & IFF_RUNNING) || (ifm->ifm_flags & IFF_NOARP)) {
34 continue;
35 }
36
37 struct sockaddr_dl* sdl = (struct sockaddr_dl*) (ifm + 1);
38 assert(sdl->sdl_family == AF_LINK);
39
40 sdl->sdl_data[sdl->sdl_nlen] = 0;
41
42 if (options->namePrefix.length && strncmp(sdl->sdl_data, options->namePrefix.chars, options->namePrefix.length) != 0) {
43 continue;
44 }
45
46 FFNetIOResult* counters = FF_LIST_ADD(FFNetIOResult, *result);
47 *counters = (FFNetIOResult) {
48 .name = ffStrbufCreateNS(sdl->sdl_nlen, sdl->sdl_data),
49 .txBytes = ifm->ifm_data.ifi_obytes,
50 .rxBytes = ifm->ifm_data.ifi_ibytes,
51 .txPackets = ifm->ifm_data.ifi_opackets,
52 .rxPackets = ifm->ifm_data.ifi_ipackets,
53 .txErrors = ifm->ifm_data.ifi_oerrors,
54 .rxErrors = ifm->ifm_data.ifi_ierrors,
55#ifdef FF_HAVE_IFI_OQDROPS
56 .txDrops = ifm->ifm_data.ifi_oqdrops,
57#else
58 .txDrops = 0, // unsupported
59#endif
60 .rxDrops = ifm->ifm_data.ifi_iqdrops,
61 .defaultRoute = sdl->sdl_index == defaultRouteIfIndex,
62 };
63 }
64
65 return nullptr;
66}