mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-11-07 13:44:18 +01:00
NetUsage: rename to NetIO
This commit is contained in:
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user