From 5e5c0b4a58a70b4b9f1a183c04b94bea8ff8f254 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 27 Sep 2023 10:13:59 +0800 Subject: [PATCH] NetIO: improve performance --- src/common/netif/netif.c | 45 ++++---- src/common/netif/netif.h | 6 +- src/common/netif/netif_bsd.c | 3 +- src/common/netif/netif_linux.c | 3 +- src/common/netif/netif_windows.c | 2 +- src/detection/localip/localip_linux.c | 4 +- src/detection/localip/localip_windows.c | 2 +- src/detection/netio/netio_bsd.c | 18 ++-- src/detection/netio/netio_linux.c | 132 +++++++++++++----------- 9 files changed, 110 insertions(+), 105 deletions(-) diff --git a/src/common/netif/netif.c b/src/common/netif/netif.c index a6aed5730..ec317454b 100644 --- a/src/common/netif/netif.c +++ b/src/common/netif/netif.c @@ -1,35 +1,30 @@ #include "netif.h" #ifndef _WIN32 -#include - -bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1]); - -const char* ffNetifGetDefaultRoute() -{ - static char iface[IF_NAMESIZE + 1]; - - if (*(uint16_t*) iface == 0) - { - if (!ffNetifGetDefaultRouteImpl(iface)) - iface[1] = 1; - } - - return iface; -} + #include #else -bool ffNetifGetDefaultRouteImpl(uint32_t* ifIndex); + #define IF_NAMESIZE 16 +#endif -uint32_t ffNetifGetDefaultRoute() +bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex); +enum { IF_INDEX_UNINITIALIZED = (uint32_t) -1, IF_INDEX_INVALID = (uint32_t) -2 }; +static uint32_t ifIndex = IF_INDEX_UNINITIALIZED; +static char ifName[IF_NAMESIZE + 1]; + +static inline void init() { - static uint32_t ifIndex = (uint32_t) -1; + if (ifIndex == (uint32_t) IF_INDEX_UNINITIALIZED && !ffNetifGetDefaultRouteImpl(ifName, &ifIndex)) + ifIndex = (uint32_t) IF_INDEX_INVALID; +} - if (ifIndex == (uint32_t) -1) - { - if (!ffNetifGetDefaultRouteImpl(&ifIndex)) - ifIndex = (uint32_t) -2; - } +const char* ffNetifGetDefaultRouteIfName() +{ + init(); + return ifName; +} +uint32_t ffNetifGetDefaultRouteIfIndex() +{ + init(); return ifIndex; } -#endif diff --git a/src/common/netif/netif.h b/src/common/netif/netif.h index 5b20e16f8..23ca5ef60 100644 --- a/src/common/netif/netif.h +++ b/src/common/netif/netif.h @@ -3,7 +3,7 @@ #include "fastfetch.h" #ifndef _WIN32 -const char* ffNetifGetDefaultRoute(); -#else -uint32_t ffNetifGetDefaultRoute(); +const char* ffNetifGetDefaultRouteIfName(); #endif + +uint32_t ffNetifGetDefaultRouteIfIndex(); diff --git a/src/common/netif/netif_bsd.c b/src/common/netif/netif_bsd.c index fcd657a30..f288d7d35 100644 --- a/src/common/netif/netif_bsd.c +++ b/src/common/netif/netif_bsd.c @@ -39,7 +39,7 @@ get_rt_address(struct rt_msghdr *rtm, int desired) return NULL; } -bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1]) +bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex) { //https://github.com/hashPirate/copenheimer-masscan-fork/blob/36f1ed9f7b751a7dccd5ed27874e2e703db7d481/src/rawsock-getif.c#L104 @@ -88,6 +88,7 @@ bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1]) assert(sdl->sdl_nlen <= IF_NAMESIZE); memcpy(iface, sdl->sdl_data, sdl->sdl_nlen); iface[sdl->sdl_nlen] = '\0'; + *ifIndex = sdl->sdl_index; return true; } return false; diff --git a/src/common/netif/netif_linux.c b/src/common/netif/netif_linux.c index f8b323b67..f645b0a0b 100644 --- a/src/common/netif/netif_linux.c +++ b/src/common/netif/netif_linux.c @@ -7,7 +7,7 @@ #define FF_STR_INDIR(x) #x #define FF_STR(x) FF_STR_INDIR(x) -bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1]) +bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex) { FILE* FF_AUTO_CLOSE_FILE netRoute = fopen("/proc/net/route", "r"); if (!netRoute) return false; @@ -21,6 +21,7 @@ bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1]) while (fscanf(netRoute, "%" FF_STR(IF_NAMESIZE) "s%llx%*[^\n]", iface, &destination) == 2) { if (destination != 0) continue; + *ifIndex = if_nametoindex(iface); return true; } return false; diff --git a/src/common/netif/netif_windows.c b/src/common/netif/netif_windows.c index 3fc80ecba..df591d5e6 100644 --- a/src/common/netif/netif_windows.c +++ b/src/common/netif/netif_windows.c @@ -3,7 +3,7 @@ #include -bool ffNetifGetDefaultRouteImpl(uint32_t* ifIndex) +bool ffNetifGetDefaultRouteImpl(char* iface/* unsupported */, uint32_t* ifIndex) { ULONG size = 0; if (GetIpForwardTable(NULL, &size, TRUE) != ERROR_INSUFFICIENT_BUFFER) diff --git a/src/detection/localip/localip_linux.c b/src/detection/localip/localip_linux.c index 38cec4233..1f319ad34 100644 --- a/src/detection/localip/localip_linux.c +++ b/src/detection/localip/localip_linux.c @@ -57,14 +57,14 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results) if(getifaddrs(&ifAddrStruct) < 0) return "getifaddrs(&ifAddrStruct) failed"; - const char* defaultRouteIface = ffNetifGetDefaultRoute(); + const char* defaultRouteIfName = ffNetifGetDefaultRouteIfName(); for (struct ifaddrs* ifa = ifAddrStruct; ifa; ifa = ifa->ifa_next) { if (!ifa->ifa_addr || !(ifa->ifa_flags & IFF_RUNNING)) continue; - bool isDefaultRoute = ffStrEquals(defaultRouteIface, ifa->ifa_name); + bool isDefaultRoute = ffStrEquals(defaultRouteIfName, ifa->ifa_name); if (options->defaultRouteOnly && !isDefaultRoute) continue; diff --git a/src/detection/localip/localip_windows.c b/src/detection/localip/localip_windows.c index 8863843fd..bb39b4325 100644 --- a/src/detection/localip/localip_windows.c +++ b/src/detection/localip/localip_windows.c @@ -70,7 +70,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results) return "GetAdaptersAddresses() failed"; } - uint32_t defaultRouteIfIndex = ffNetifGetDefaultRoute(); + uint32_t defaultRouteIfIndex = ffNetifGetDefaultRouteIfIndex(); // Iterate through all of the adapters for (IP_ADAPTER_ADDRESSES* adapter = adapter_addresses; adapter; adapter = adapter->Next) diff --git a/src/detection/netio/netio_bsd.c b/src/detection/netio/netio_bsd.c index a0c764dbd..57e36d086 100644 --- a/src/detection/netio/netio_bsd.c +++ b/src/detection/netio/netio_bsd.c @@ -14,15 +14,15 @@ const char* ffNetIOGetIoCounters(FFlist* result, FFNetIOOptions* options) { + uint32_t defaultRouteIfIndex = ffNetifGetDefaultRouteIfIndex(); + 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"; + if (sysctl((int[]) { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST2, (options->defaultRouteOnly ? (int) defaultRouteIfIndex : 0) }, 6, NULL, &bufSize, 0, 0) < 0) + return "sysctl({ CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST2, ifIndex }, 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(); + if (sysctl((int[]) { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST2, (options->defaultRouteOnly ? (int) defaultRouteIfIndex : 0) }, 6, buf, &bufSize, 0, 0) < 0) + return "sysctl({ CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST2, ifIndex }, 6, buf, &bufSize, 0, 0) failed"; for (struct if_msghdr2* ifm = buf; ifm < (struct if_msghdr2*) ((uint8_t*) buf + bufSize); @@ -36,10 +36,6 @@ const char* ffNetIOGetIoCounters(FFlist* result, FFNetIOOptions* options) 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; @@ -54,7 +50,7 @@ const char* ffNetIOGetIoCounters(FFlist* result, FFNetIOOptions* options) .rxErrors = ifm->ifm_data.ifi_ierrors, .txDrops = 0, // unsupported .rxDrops = ifm->ifm_data.ifi_iqdrops, - .defaultRoute = isDefaultRoute, + .defaultRoute = sdl->sdl_index == defaultRouteIfIndex, }; } diff --git a/src/detection/netio/netio_linux.c b/src/detection/netio/netio_linux.c index 4b5565cbc..2b1f24478 100644 --- a/src/detection/netio/netio_linux.c +++ b/src/detection/netio/netio_linux.c @@ -6,6 +6,60 @@ #include +static void getData(FFstrbuf* buffer, const char* ifName, bool isDefaultRoute, FFstrbuf* path, FFlist* result) +{ + ffStrbufSetF(path, "/sys/class/net/%s/operstate", ifName); + if(!ffReadFileBuffer(path->chars, buffer) || !ffStrbufEqualS(buffer, "up")) + return; + + FFNetIOResult* counters = (FFNetIOResult*) ffListAdd(result); + ffStrbufInitS(&counters->name, ifName); + counters->defaultRoute = isDefaultRoute; + + ffStrbufSetF(path, "/sys/class/net/%s/statistics/", ifName); + 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); +} + const char* ffNetIOGetIoCounters(FFlist* result, FFNetIOOptions* options) { FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/sys/class/net"); @@ -14,71 +68,29 @@ const char* ffNetIOGetIoCounters(FFlist* result, FFNetIOOptions* options) FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateA(64); FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); - const char* defaultRouteIface = ffNetifGetDefaultRoute(); + const char* defaultRouteIfName = ffNetifGetDefaultRouteIfName(); - struct dirent* entry; - while((entry = readdir(dirp)) != NULL) + if (options->defaultRouteOnly) { - if(entry->d_name[0] == '.') - continue; + if (options->namePrefix.length && strncmp(defaultRouteIfName, options->namePrefix.chars, options->namePrefix.length) != 0) + return NULL; - bool isDefaultRoute = ffStrEquals(entry->d_name, defaultRouteIface); - if(options->defaultRouteOnly && !isDefaultRoute) - continue; + getData(&buffer, defaultRouteIfName, true, &path, result); + } + else + { + struct dirent* entry; + while((entry = readdir(dirp)) != NULL) + { + const char* ifName = entry->d_name; + if(ifName[0] == '.') + continue; - if (options->namePrefix.length && strncmp(entry->d_name, options->namePrefix.chars, options->namePrefix.length) != 0) - continue; + if (options->namePrefix.length && strncmp(ifName, 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); + getData(&buffer, ifName, ffStrEquals(ifName, defaultRouteIfName), &path, result); + } } return NULL;