NetUsage: rename to NetIO

This commit is contained in:
李通洲
2023-09-27 00:05:37 +08:00
parent 3866f27448
commit 154657b455
26 changed files with 102 additions and 102 deletions
+67
View File
@@ -0,0 +1,67 @@
#include "netio.h"
#include "common/time.h"
const char* ffNetIOGetIoCounters(FFlist* result, FFNetIOOptions* options);
static FFlist ioCounters1;
static uint64_t time1;
void ffPrepareNetIO(FFNetIOOptions* options)
{
ffListInit(&ioCounters1, sizeof(FFNetIOResult));
ffNetIOGetIoCounters(&ioCounters1, options);
time1 = ffTimeGetNow();
}
const char* ffDetectNetIO(FFlist* result, FFNetIOOptions* options)
{
const char* error = NULL;
if (time1 == 0)
{
ffListInit(&ioCounters1, sizeof(FFNetIOResult));
error = ffNetIOGetIoCounters(&ioCounters1, options);
if (error)
return error;
time1 = ffTimeGetNow();
}
if (ioCounters1.length == 0)
return "No network interfaces found";
uint64_t time2 = ffTimeGetNow();
while (time2 - time1 < 1000)
{
ffTimeSleep((uint32_t) (1000 - (time2 - time1)));
time2 = ffTimeGetNow();
}
error = ffNetIOGetIoCounters(result, options);
if (error)
return error;
if (result->length != ioCounters1.length)
return "Different number of network interfaces. Network change?";
for (uint32_t i = 0; i < result->length; ++i)
{
FFNetIOResult* icPrev = (FFNetIOResult*)ffListGet(&ioCounters1, i);
FFNetIOResult* icCurr = (FFNetIOResult*)ffListGet(result, i);
if (!ffStrbufEqual(&icPrev->name, &icCurr->name))
return "Network interface name changed";
static_assert(sizeof(FFNetIOResult) - offsetof(FFNetIOResult, txBytes) == sizeof(uint64_t) * 8, "Unexpected struct FFNetIOResult layout");
for (size_t off = offsetof(FFNetIOResult, txBytes); off < sizeof(FFNetIOResult); off += sizeof(uint64_t))
{
uint64_t* prevValue = (uint64_t*) ((uint8_t*) icPrev + off);
uint64_t* currValue = (uint64_t*) ((uint8_t*) icCurr + off);
uint64_t temp = *currValue;
*currValue -= *prevValue;
*currValue /= (time2 - time1) / 1000 /* seconds */;
*prevValue = temp;
}
}
time1 = time2;
return NULL;
}
+17
View File
@@ -0,0 +1,17 @@
#include "fastfetch.h"
typedef struct FFNetIOResult
{
FFstrbuf name;
bool defaultRoute;
uint64_t txBytes;
uint64_t rxBytes;
uint64_t txPackets;
uint64_t rxPackets;
uint64_t rxErrors;
uint64_t txErrors;
uint64_t rxDrops;
uint64_t txDrops;
} FFNetIOResult;
const char* ffDetectNetIO(FFlist* result, FFNetIOOptions* options);
+62
View File
@@ -0,0 +1,62 @@
#include "netio.h"
#include "common/io/io.h"
#include "common/netif/netif.h"
#include "util/stringUtils.h"
#include "util/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)
{
size_t bufSize = 0;
if (sysctl((int[]) { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST2, 0 }, 6, NULL, &bufSize, 0, 0) < 0)
return "sysctl({ CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST2, 0 }, 6, NULL, &bufSize, 0, 0) failed";
FF_AUTO_FREE struct if_msghdr2* buf = (struct if_msghdr2*) malloc(bufSize);
if (sysctl((int[]) { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST2, 0 }, 6, buf, &bufSize, 0, 0) < 0)
return "sysctl({ CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST2, 0 }, 6, buf, &bufSize, 0, 0) failed";
const char* defaultRouteIface = ffNetifGetDefaultRoute();
for (struct if_msghdr2* ifm = buf;
ifm < (struct if_msghdr2*) ((uint8_t*) buf + bufSize);
ifm = (struct if_msghdr2*) ((uint8_t*) ifm + ifm->ifm_msglen))
{
if (ifm->ifm_type != RTM_IFINFO2 || !(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);
if (sdl->sdl_type != IFT_ETHER && !(ifm->ifm_flags & IFF_LOOPBACK)) continue;
sdl->sdl_data[sdl->sdl_nlen] = 0;
bool isDefaultRoute = ffStrEquals(sdl->sdl_data, defaultRouteIface);
if(options->defaultRouteOnly && !isDefaultRoute)
continue;
if (options->namePrefix.length && strncmp(sdl->sdl_data, options->namePrefix.chars, options->namePrefix.length) != 0)
continue;
FFNetIOResult* counters = (FFNetIOResult*) ffListAdd(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,
.txDrops = 0, // unsupported
.rxDrops = ifm->ifm_data.ifi_iqdrops,
.defaultRoute = isDefaultRoute,
};
}
return NULL;
}
+85
View File
@@ -0,0 +1,85 @@
#include "netio.h"
#include "common/io/io.h"
#include "common/netif/netif.h"
#include "util/stringUtils.h"
#include <net/if.h>
const char* ffNetIOGetIoCounters(FFlist* result, FFNetIOOptions* options)
{
FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/sys/class/net");
if (!dirp) return "opendir(\"/sys/class/net\") == NULL";
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateA(64);
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
const char* defaultRouteIface = ffNetifGetDefaultRoute();
struct dirent* entry;
while((entry = readdir(dirp)) != NULL)
{
if(entry->d_name[0] == '.')
continue;
bool isDefaultRoute = ffStrEquals(entry->d_name, defaultRouteIface);
if(options->defaultRouteOnly && !isDefaultRoute)
continue;
if (options->namePrefix.length && strncmp(entry->d_name, options->namePrefix.chars, options->namePrefix.length) != 0)
continue;
ffStrbufSetF(&path, "/sys/class/net/%s/operstate", entry->d_name);
if(!ffReadFileBuffer(path.chars, &buffer) || !ffStrbufEqualS(&buffer, "up"))
continue;
FFNetIOResult* counters = (FFNetIOResult*) ffListAdd(result);
ffStrbufInitS(&counters->name, entry->d_name);
counters->defaultRoute = isDefaultRoute;
ffStrbufSetF(&path, "/sys/class/net/%s/statistics/", entry->d_name);
uint32_t statLen = path.length;
ffStrbufAppendS(&path, "rx_bytes");
if (ffReadFileBuffer(path.chars, &buffer))
counters->rxBytes = ffStrbufToUInt(&buffer, 0);
ffStrbufSubstrBefore(&path, statLen);
ffStrbufAppendS(&path, "tx_bytes");
if (ffReadFileBuffer(path.chars, &buffer))
counters->txBytes = ffStrbufToUInt(&buffer, 0);
ffStrbufSubstrBefore(&path, statLen);
ffStrbufAppendS(&path, "rx_packets");
if (ffReadFileBuffer(path.chars, &buffer))
counters->rxPackets = ffStrbufToUInt(&buffer, 0);
ffStrbufSubstrBefore(&path, statLen);
ffStrbufAppendS(&path, "tx_packets");
if (ffReadFileBuffer(path.chars, &buffer))
counters->txPackets = ffStrbufToUInt(&buffer, 0);
ffStrbufSubstrBefore(&path, statLen);
ffStrbufAppendS(&path, "rx_errors");
if (ffReadFileBuffer(path.chars, &buffer))
counters->rxErrors = ffStrbufToUInt(&buffer, 0);
ffStrbufSubstrBefore(&path, statLen);
ffStrbufAppendS(&path, "tx_errors");
if (ffReadFileBuffer(path.chars, &buffer))
counters->txErrors = ffStrbufToUInt(&buffer, 0);
ffStrbufSubstrBefore(&path, statLen);
ffStrbufAppendS(&path, "rx_dropped");
if (ffReadFileBuffer(path.chars, &buffer))
counters->rxDrops = ffStrbufToUInt(&buffer, 0);
ffStrbufSubstrBefore(&path, statLen);
ffStrbufAppendS(&path, "tx_dropped");
if (ffReadFileBuffer(path.chars, &buffer))
counters->txDrops = ffStrbufToUInt(&buffer, 0);
ffStrbufSubstrBefore(&path, statLen);
}
return NULL;
}
+74
View File
@@ -0,0 +1,74 @@
#include "netio.h"
#include "common/netif/netif.h"
#include "util/mallocHelper.h"
#include "util/windows/unicode.h"
#include <ws2tcpip.h>
#include <iphlpapi.h>
const char* ffNetIOGetIoCounters(FFlist* result, FFNetIOOptions* options)
{
IP_ADAPTER_ADDRESSES* FF_AUTO_FREE adapter_addresses = NULL;
// Multiple attempts in case interfaces change while
// we are in the middle of querying them.
DWORD adapter_addresses_buffer_size = 0;
for (int attempts = 0;; ++attempts)
{
if (adapter_addresses_buffer_size)
{
adapter_addresses = (IP_ADAPTER_ADDRESSES*)realloc(adapter_addresses, adapter_addresses_buffer_size);
assert(adapter_addresses);
}
DWORD error = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER,
NULL,
adapter_addresses,
&adapter_addresses_buffer_size);
if (error == ERROR_SUCCESS)
break;
else if (ERROR_BUFFER_OVERFLOW == error && attempts < 4)
continue;
else
return "GetAdaptersAddresses() failed";
}
uint32_t defaultRouteIfIndex = ffNetifGetDefaultRoute();
// Iterate through all of the adapters
for (IP_ADAPTER_ADDRESSES* adapter = adapter_addresses; adapter; adapter = adapter->Next)
{
bool isDefaultRoute = adapter->IfIndex == defaultRouteIfIndex;
if (options->defaultRouteOnly && !isDefaultRoute)
continue;
char name[128];
WideCharToMultiByte(CP_UTF8, 0, adapter->FriendlyName, -1, name, sizeof(name), NULL, NULL);
if (options->namePrefix.length && strncmp(name, options->namePrefix.chars, options->namePrefix.length) != 0)
continue;
MIB_IF_ROW2 ifRow = { .InterfaceIndex = adapter->IfIndex };
if (GetIfEntry2(&ifRow) == NO_ERROR)
{
FFNetIOResult* counters = (FFNetIOResult*) ffListAdd(result);
*counters = (FFNetIOResult) {
.name = ffStrbufCreateS(name),
.txBytes = ifRow.OutOctets,
.rxBytes = ifRow.InOctets,
.txPackets = (ifRow.OutUcastPkts + ifRow.OutNUcastPkts),
.rxPackets = (ifRow.InUcastPkts + ifRow.InNUcastPkts),
.rxErrors = ifRow.InErrors,
.txErrors = ifRow.OutErrors,
.rxDrops = ifRow.InDiscards,
.txDrops = ifRow.OutDiscards,
.defaultRoute = isDefaultRoute,
};
}
}
return NULL;
}