Skip to content

Commit b29b78b

Browse files
committed
NetUsage: finish module
1 parent 917b049 commit b29b78b

File tree

12 files changed

+145
-23
lines changed

12 files changed

+145
-23
lines changed

doc/json_schema.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,7 @@
558558
"media",
559559
"memory",
560560
"monitor",
561+
"netusage",
561562
"opencl",
562563
"opengl",
563564
"os",
@@ -1019,6 +1020,36 @@
10191020
},
10201021
"additionalProperties": false
10211022
},
1023+
{
1024+
"title": "Network throughput (usage)",
1025+
"properties": {
1026+
"type": {
1027+
"const": "netusage"
1028+
},
1029+
"namePrefix": {
1030+
"title": "Show IPs with given name prefix only",
1031+
"type": "string"
1032+
},
1033+
"defaultRouteOnly": {
1034+
"title": "Show ips that are used for default routing only",
1035+
"type": "boolean",
1036+
"default": false
1037+
},
1038+
"key": {
1039+
"$ref": "#/$defs/key"
1040+
},
1041+
"keyColor": {
1042+
"$ref": "#/$defs/keyColor"
1043+
},
1044+
"keyWidth": {
1045+
"$ref": "#/$defs/keyWidth"
1046+
},
1047+
"format": {
1048+
"$ref": "#/$defs/format"
1049+
}
1050+
},
1051+
"additionalProperties": false
1052+
},
10221053
{
10231054
"title": "OpenGL",
10241055
"properties": {

src/common/commandoption.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ void ffPrepareCommandOption(FFdata* data)
6161
ffPrepareCPUUsage();
6262

6363
if(ffStrbufContainIgnCaseS(&data->structure, FF_NETUSAGE_MODULE_NAME))
64-
ffPrepareNetUsage();
64+
ffPrepareNetUsage(&instance.config.netUsage);
6565

6666
if(instance.config.multithreading)
6767
{

src/common/jsonconfig.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,14 @@ static void prepareModuleJsonObject(const char* type, yyjson_val* module)
112112
ffPrepareCPUUsage();
113113
break;
114114
}
115+
case 'n': case 'N': {
116+
if (ffStrEqualsIgnCase(type, FF_NETUSAGE_MODULE_NAME))
117+
{
118+
if (module) ffParseNetUsageJsonObject(&cfg->netUsage, module);
119+
ffPrepareNetUsage(&cfg->netUsage);
120+
}
121+
break;
122+
}
115123
case 'p': case 'P': {
116124
if (ffStrEqualsIgnCase(type, FF_PUBLICIP_MODULE_NAME))
117125
{

src/detection/netusage/netusage.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,41 @@
22

33
#include "common/time.h"
44

5-
const char* ffNetUsageGetIoCounters(FFlist* result);
5+
const char* ffNetUsageGetIoCounters(FFlist* result, FFNetUsageOptions* options);
66

77
static FFlist ioCounters1;
88
static uint64_t time1;
99

10-
void ffPrepareNetUsage(void)
10+
void ffPrepareNetUsage(FFNetUsageOptions* options)
1111
{
1212
ffListInit(&ioCounters1, sizeof(FFNetUsageIoCounters));
13-
ffNetUsageGetIoCounters(&ioCounters1);
13+
ffNetUsageGetIoCounters(&ioCounters1, options);
1414
time1 = ffTimeGetNow();
1515
}
1616

17-
const char* ffDetectNetUsage(FFlist* result)
17+
const char* ffDetectNetUsage(FFlist* result, FFNetUsageOptions* options)
1818
{
1919
const char* error = NULL;
2020
if (time1 == 0)
2121
{
2222
ffListInit(&ioCounters1, sizeof(FFNetUsageIoCounters));
23-
error = ffNetUsageGetIoCounters(&ioCounters1);
23+
error = ffNetUsageGetIoCounters(&ioCounters1, options);
2424
if (error)
2525
return error;
2626
time1 = ffTimeGetNow();
27-
ffTimeSleep(1000);
2827
}
2928

29+
if (ioCounters1.length == 0)
30+
return "No network interfaces found";
31+
3032
uint64_t time2 = ffTimeGetNow();
3133
while (time2 - time1 < 1000)
3234
{
3335
ffTimeSleep((uint32_t) (1000 - (time2 - time1)));
3436
time2 = ffTimeGetNow();
3537
}
3638

37-
error = ffNetUsageGetIoCounters(result);
39+
error = ffNetUsageGetIoCounters(result, options);
3840
if (error)
3941
return error;
4042

src/detection/netusage/netusage.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
typedef struct FFNetUsageIoCounters
44
{
55
FFstrbuf name;
6+
bool defaultRoute;
67
uint64_t txBytes;
78
uint64_t rxBytes;
89
uint64_t txPackets;
@@ -13,4 +14,4 @@ typedef struct FFNetUsageIoCounters
1314
uint64_t txDrops;
1415
} FFNetUsageIoCounters;
1516

16-
const char* ffDetectNetUsage(FFlist* result);
17+
const char* ffDetectNetUsage(FFlist* result, FFNetUsageOptions* options);

src/detection/netusage/netusage_bsd.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "netusage.h"
22

33
#include "common/io/io.h"
4+
#include "common/netif/netif.h"
45
#include "util/mallocHelper.h"
56

67
#include <net/if.h>
@@ -10,7 +11,7 @@
1011
#include <sys/sysctl.h>
1112
#include <sys/socket.h>
1213

13-
const char* ffNetUsageGetIoCounters(FFlist* result)
14+
const char* ffNetUsageGetIoCounters(FFlist* result, FFNetUsageOptions* options)
1415
{
1516
size_t bufSize = 0;
1617
if (sysctl((int[]) { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST2, 0 }, 6, NULL, &bufSize, 0, 0) < 0)
@@ -20,6 +21,8 @@ const char* ffNetUsageGetIoCounters(FFlist* result)
2021
if (sysctl((int[]) { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST2, 0 }, 6, buf, &bufSize, 0, 0) < 0)
2122
return "sysctl({ CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST2, 0 }, 6, buf, &bufSize, 0, 0) failed";
2223

24+
const char* defaultRouteIface = ffNetifGetDefaultRoute();
25+
2326
for (struct if_msghdr2* ifm = buf;
2427
ifm < (struct if_msghdr2*) ((uint8_t*) buf + bufSize);
2528
ifm = (struct if_msghdr2*) ((uint8_t*) ifm + ifm->ifm_msglen))
@@ -29,9 +32,19 @@ const char* ffNetUsageGetIoCounters(FFlist* result)
2932
struct sockaddr_dl* sdl = (struct sockaddr_dl*) (ifm + 1);
3033
assert(sdl->sdl_family == AF_LINK);
3134
if (sdl->sdl_type != IFT_ETHER && !(ifm->ifm_flags & IFF_LOOPBACK)) continue;
32-
FFNetUsageIoCounters* counters = (FFNetUsageIoCounters*) ffListAdd(result);
3335

36+
sdl->sdl_data[sdl->sdl_nlen] = 0;
37+
38+
bool isDefaultRoute = ffStrEquals(sdl->sdl_data, defaultRouteIface);
39+
if(options->defaultRouteOnly && !isDefaultRoute)
40+
continue;
41+
42+
if (options->namePrefix.length && strncmp(sdl->sdl_data, options->namePrefix.chars, options->namePrefix.length) != 0)
43+
continue;
44+
45+
FFNetUsageIoCounters* counters = (FFNetUsageIoCounters*) ffListAdd(result);
3446
*counters = (FFNetUsageIoCounters) {
47+
.name = ffStrbufCreateNS(sdl->sdl_nlen, sdl->sdl_data),
3548
.txBytes = ifm->ifm_data.ifi_obytes,
3649
.rxBytes = ifm->ifm_data.ifi_ibytes,
3750
.txPackets = ifm->ifm_data.ifi_opackets,
@@ -40,9 +53,8 @@ const char* ffNetUsageGetIoCounters(FFlist* result)
4053
.rxErrors = ifm->ifm_data.ifi_ierrors,
4154
.txDrops = 0, // unsupported
4255
.rxDrops = ifm->ifm_data.ifi_iqdrops,
56+
.defaultRoute = isDefaultRoute,
4357
};
44-
45-
ffStrbufInitNS(&counters->name, sdl->sdl_nlen, sdl->sdl_data);
4658
}
4759

4860
return NULL;

src/detection/netusage/netusage_linux.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,43 @@
11
#include "netusage.h"
22

33
#include "common/io/io.h"
4+
#include "common/netif/netif.h"
5+
#include "util/stringUtils.h"
46

57
#include <net/if.h>
68

7-
const char* ffNetUsageGetIoCounters(FFlist* result)
9+
const char* ffNetUsageGetIoCounters(FFlist* result, FFNetUsageOptions* options)
810
{
911
FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/sys/class/net");
1012
if (!dirp) return "opendir(\"/sys/class/net\") == NULL";
1113

1214
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateA(64);
1315
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
1416

17+
const char* defaultRouteIface = ffNetifGetDefaultRoute();
18+
1519
struct dirent* entry;
1620
while((entry = readdir(dirp)) != NULL)
1721
{
1822
if(entry->d_name[0] == '.')
1923
continue;
2024

25+
bool isDefaultRoute = ffStrEquals(entry->d_name, defaultRouteIface);
26+
if(options->defaultRouteOnly && !isDefaultRoute)
27+
continue;
28+
29+
if (options->namePrefix.length && strncmp(entry->d_name, options->namePrefix.chars, options->namePrefix.length) != 0)
30+
continue;
31+
2132
ffStrbufSetF(&path, "/sys/class/net/%s/operstate", entry->d_name);
2233
if(!ffReadFileBuffer(path.chars, &buffer) || !ffStrbufEqualS(&buffer, "up"))
2334
continue;
2435

2536
FFNetUsageIoCounters* counters = (FFNetUsageIoCounters*) ffListAdd(result);
2637
ffStrbufInitS(&counters->name, entry->d_name);
38+
counters->defaultRoute = isDefaultRoute;
2739

28-
ffStrbufSetF(&path, "/sys/class/net/%s/statistics/");
40+
ffStrbufSetF(&path, "/sys/class/net/%s/statistics/", entry->d_name);
2941
uint32_t statLen = path.length;
3042

3143
ffStrbufAppendS(&path, "rx_bytes");

src/detection/netusage/netusage_windows.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
#include "netusage.h"
22

3-
#include "common/io/io.h"
3+
#include "common/netif/netif.h"
44
#include "util/mallocHelper.h"
55
#include "util/windows/unicode.h"
66

77
#include <ws2tcpip.h>
88
#include <iphlpapi.h>
99

10-
const char* ffNetUsageGetIoCounters(FFlist* result)
10+
const char* ffNetUsageGetIoCounters(FFlist* result, FFNetUsageOptions* options)
1111
{
1212
IP_ADAPTER_ADDRESSES* FF_AUTO_FREE adapter_addresses = NULL;
1313

@@ -37,14 +37,26 @@ const char* ffNetUsageGetIoCounters(FFlist* result)
3737
return "GetAdaptersAddresses() failed";
3838
}
3939

40+
uint32_t defaultRouteIfIndex = ffNetifGetDefaultRoute();
41+
4042
// Iterate through all of the adapters
4143
for (IP_ADAPTER_ADDRESSES* adapter = adapter_addresses; adapter; adapter = adapter->Next)
4244
{
45+
bool isDefaultRoute = adapter->IfIndex == defaultRouteIfIndex;
46+
if (options->defaultRouteOnly && !isDefaultRoute)
47+
continue;
48+
49+
char name[128];
50+
WideCharToMultiByte(CP_UTF8, 0, adapter->FriendlyName, -1, name, sizeof(name), NULL, NULL);
51+
if (options->namePrefix.length && strncmp(name, options->namePrefix.chars, options->namePrefix.length) != 0)
52+
continue;
53+
4354
MIB_IF_ROW2 ifRow = { .InterfaceIndex = adapter->IfIndex };
4455
if (GetIfEntry2(&ifRow) == NO_ERROR)
4556
{
4657
FFNetUsageIoCounters* counters = (FFNetUsageIoCounters*) ffListAdd(result);
4758
*counters = (FFNetUsageIoCounters) {
59+
.name = ffStrbufCreateS(name),
4860
.txBytes = ifRow.OutOctets,
4961
.rxBytes = ifRow.InOctets,
5062
.txPackets = (ifRow.OutUcastPkts + ifRow.OutNUcastPkts),
@@ -53,8 +65,8 @@ const char* ffNetUsageGetIoCounters(FFlist* result)
5365
.txErrors = ifRow.OutErrors,
5466
.rxDrops = ifRow.InDiscards,
5567
.txDrops = ifRow.OutDiscards,
68+
.defaultRoute = isDefaultRoute,
5669
};
57-
ffStrbufSetWS(&counters->name, adapter->FriendlyName);
5870
}
5971
}
6072

src/modules/netusage/netusage.c

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ static void formatKey(const FFNetUsageOptions* options, FFNetUsageIoCounters* in
3535
void ffPrintNetUsage(FFNetUsageOptions* options)
3636
{
3737
FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFNetUsageIoCounters));
38-
const char* error = ffDetectNetUsage(&result);
38+
const char* error = ffDetectNetUsage(&result, options);
3939

4040
if(error)
4141
{
@@ -63,6 +63,8 @@ void ffPrintNetUsage(FFNetUsageOptions* options)
6363
ffStrbufAppendS(&buffer, "/s (in) - ");
6464
ffParseSize(inf->txBytes, &buffer);
6565
ffStrbufAppendS(&buffer, "/s (out)");
66+
if (!options->defaultRouteOnly && inf->defaultRoute)
67+
ffStrbufAppendS(&buffer, " *");
6668
ffStrbufPutTo(&buffer, stdout);
6769
}
6870
else
@@ -82,16 +84,25 @@ void ffPrintNetUsage(FFNetUsageOptions* options)
8284
{FF_FORMAT_ARG_TYPE_UINT64, &inf->txErrors},
8385
{FF_FORMAT_ARG_TYPE_UINT64, &inf->rxDrops},
8486
{FF_FORMAT_ARG_TYPE_UINT64, &inf->txDrops},
87+
{FF_FORMAT_ARG_TYPE_BOOL, &inf->defaultRoute},
8588
});
8689
}
8790
++index;
8891
}
92+
93+
FF_LIST_FOR_EACH(FFNetUsageIoCounters, inf, result)
94+
{
95+
ffStrbufDestroy(&inf->name);
96+
}
8997
}
9098

9199
void ffInitNetUsageOptions(FFNetUsageOptions* options)
92100
{
93101
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_NETUSAGE_MODULE_NAME, ffParseNetUsageCommandOptions, ffParseNetUsageJsonObject, ffPrintNetUsage, ffGenerateNetUsageJson);
94102
ffOptionInitModuleArg(&options->moduleArgs);
103+
104+
ffStrbufInit(&options->namePrefix);
105+
options->defaultRouteOnly = false;
95106
}
96107

97108
bool ffParseNetUsageCommandOptions(FFNetUsageOptions* options, const char* key, const char* value)
@@ -101,12 +112,25 @@ bool ffParseNetUsageCommandOptions(FFNetUsageOptions* options, const char* key,
101112
if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs))
102113
return true;
103114

115+
if (ffStrEqualsIgnCase(subKey, "name-prefix"))
116+
{
117+
ffOptionParseString(key, value, &options->namePrefix);
118+
return true;
119+
}
120+
121+
if (ffStrEqualsIgnCase(subKey, "default-route-only"))
122+
{
123+
options->defaultRouteOnly = ffOptionParseBoolean(value);
124+
return true;
125+
}
126+
104127
return false;
105128
}
106129

107130
void ffDestroyNetUsageOptions(FFNetUsageOptions* options)
108131
{
109132
ffOptionDestroyModuleArg(&options->moduleArgs);
133+
ffStrbufDestroy(&options->namePrefix);
110134
}
111135

112136
void ffParseNetUsageJsonObject(FFNetUsageOptions* options, yyjson_val* module)
@@ -122,14 +146,26 @@ void ffParseNetUsageJsonObject(FFNetUsageOptions* options, yyjson_val* module)
122146
if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs))
123147
continue;
124148

149+
if (ffStrEqualsIgnCase(key, "namePrefix"))
150+
{
151+
ffStrbufSetS(&options->namePrefix, yyjson_get_str(val));
152+
continue;
153+
}
154+
155+
if (ffStrEqualsIgnCase(key, "defaultRouteOnly"))
156+
{
157+
options->defaultRouteOnly = yyjson_get_bool(val);
158+
continue;
159+
}
160+
125161
ffPrintError(FF_NETUSAGE_MODULE_NAME, 0, &options->moduleArgs, "Unknown JSON key %s", key);
126162
}
127163
}
128164

129-
void ffGenerateNetUsageJson(FF_MAYBE_UNUSED FFNetUsageOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
165+
void ffGenerateNetUsageJson(FFNetUsageOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
130166
{
131167
FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFNetUsageIoCounters));
132-
const char* error = ffDetectNetUsage(&result);
168+
const char* error = ffDetectNetUsage(&result, options);
133169

134170
if(error)
135171
{
@@ -150,6 +186,11 @@ void ffGenerateNetUsageJson(FF_MAYBE_UNUSED FFNetUsageOptions* options, yyjson_m
150186
yyjson_mut_obj_add_uint(doc, obj, "txErrors", counter->txErrors);
151187
yyjson_mut_obj_add_uint(doc, obj, "rxDrops", counter->rxDrops);
152188
yyjson_mut_obj_add_uint(doc, obj, "txDrops", counter->txDrops);
189+
yyjson_mut_obj_add_bool(doc, obj, "defaultRoute", counter->defaultRoute);
190+
}
153191

192+
FF_LIST_FOR_EACH(FFNetUsageIoCounters, inf, result)
193+
{
194+
ffStrbufDestroy(&inf->name);
154195
}
155196
}

0 commit comments

Comments
 (0)