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