Wifi: add new module

Only Windows is supported currently
This commit is contained in:
李通洲 2022-11-26 18:23:08 +08:00
parent 5c381460ce
commit a55add190c
No known key found for this signature in database
GPG Key ID: 6E72B663408769DE
11 changed files with 410 additions and 6 deletions

View File

@ -289,6 +289,7 @@ set(LIBFASTFETCH_SRC
src/modules/users.c
src/modules/vulkan.c
src/modules/weather.c
src/modules/wifi.c
src/modules/wm.c
src/modules/wmtheme.c
src/util/FFlist.c
@ -331,6 +332,7 @@ if(LINUX)
src/detection/terminalshell/terminalshell_linux.c
src/detection/uptime/uptime_linux.c
src/detection/users/users_linux.c
src/detection/wifi/wifi_nosupport.c
src/detection/wmtheme/wmtheme_linux.c
)
elseif(ANDROID)
@ -362,6 +364,7 @@ elseif(ANDROID)
src/detection/terminalshell/terminalshell_linux.c
src/detection/uptime/uptime_linux.c
src/detection/users/users_linux.c
src/detection/wifi/wifi_nosupport.c
src/detection/wmtheme/wmtheme_nosupport.c
)
elseif(BSD)
@ -400,6 +403,7 @@ elseif(BSD)
src/detection/terminalshell/terminalshell_linux.c
src/detection/uptime/uptime_bsd.c
src/detection/users/users_linux.c
src/detection/wifi/wifi_nosupport.c
src/detection/wmtheme/wmtheme_linux.c
)
elseif(APPLE)
@ -433,6 +437,7 @@ elseif(APPLE)
src/detection/terminalshell/terminalshell_linux.c
src/detection/uptime/uptime_bsd.c
src/detection/users/users_linux.c
src/detection/wifi/wifi_nosupport.c
src/detection/wmtheme/wmtheme_apple.m
src/util/apple/cf_helpers.c
src/util/apple/osascript.m
@ -465,6 +470,7 @@ elseif(WIN32)
src/detection/terminalshell/terminalshell_windows.cpp
src/detection/uptime/uptime_windows.c
src/detection/users/users_windows.c
src/detection/wifi/wifi_windows.c
src/detection/wmtheme/wmtheme_windows.c
src/util/windows/getline.c
src/util/windows/pwd.c
@ -652,6 +658,7 @@ elseif(WIN32)
PRIVATE "setupapi"
PRIVATE "dxgi"
PRIVATE "wtsapi32"
PRIVATE "wlanapi.lib"
)
if(USE_WIN_NTAPI)
target_compile_definitions(libfastfetch PRIVATE FF_USE_WIN_NTAPI)

View File

@ -307,6 +307,9 @@ __fastfetch_completion()
"--public-ip-key"
"--public-ip-format"
"--public-ip-error"
"--wifi-key"
"--wifi-format"
"--wifi-error"
"--weather-key"
"--weather-format"
"--weather-error"

View File

@ -16,11 +16,6 @@
#include <signal.h>
#endif
static bool strbufEqualsAdapter(const void* first, const void* second)
{
return ffStrbufComp(second, first) == 0;
}
static void initConfigDirs(FFstate* state)
{
ffListInit(&state->configDirs, sizeof(FFstrbuf));
@ -35,7 +30,7 @@ static void initConfigDirs(FFstate* state)
}
#define FF_ENSURE_ONLY_ONCE_IN_LIST(element) \
if(ffListFirstIndexComp(&state->configDirs, element, strbufEqualsAdapter) < state->configDirs.length - 1) \
if(ffListFirstIndexComp(&state->configDirs, element, (bool(*)(const void*, const void*))ffStrbufEqual) < state->configDirs.length - 1) \
{ \
ffStrbufDestroy(ffListGet(&state->configDirs, state->configDirs.length - 1)); \
--state->configDirs.length; \
@ -214,6 +209,7 @@ static void defaultConfig(FFinstance* instance)
initModuleArg(&instance->config.localIP);
initModuleArg(&instance->config.publicIP);
initModuleArg(&instance->config.weather);
initModuleArg(&instance->config.wifi);
initModuleArg(&instance->config.player);
initModuleArg(&instance->config.song);
initModuleArg(&instance->config.dateTime);
@ -441,6 +437,7 @@ static void destroyConfig(FFinstance* instance)
destroyModuleArg(&instance->config.localIP);
destroyModuleArg(&instance->config.publicIP);
destroyModuleArg(&instance->config.weather);
destroyModuleArg(&instance->config.wifi);
destroyModuleArg(&instance->config.player);
destroyModuleArg(&instance->config.song);
destroyModuleArg(&instance->config.dateTime);

View File

@ -237,6 +237,7 @@
#--locale-key Locale
#--local-ip-key Local IP ({1})
#--public-ip-key Public IP
#--wifi-key Wifi
#--weather-key Weather
#--player-key Media Player
#--song-key Song

44
src/detection/wifi/wifi.h Normal file
View File

@ -0,0 +1,44 @@
#pragma once
#ifndef FF_INCLUDED_detection_wifi_wifi
#define FF_INCLUDED_detection_wifi_wifi
#include "fastfetch.h"
struct FFWifiInterface
{
FFstrbuf description;
FFstrbuf status;
};
struct FFWifiConnection
{
FFstrbuf status;
FFstrbuf ssid;
FFstrbuf macAddress;
FFstrbuf phyType;
double signalQuality; // Percentage
double rxRate;
double txRate;
};
struct FFWifiSecurity
{
bool enabled;
bool oneXEnabled;
FFstrbuf authAlgo;
FFstrbuf cipherAlgo;
};
typedef struct FFWifiResult
{
struct FFWifiInterface inf;
struct FFWifiConnection conn;
struct FFWifiSecurity security;
FFstrbuf error;
} FFWifiResult;
void ffDetectWifi(const FFinstance* instance, FFWifiResult* result);
#endif

View File

@ -0,0 +1,7 @@
#include "wifi.h"
void ffDetectWifi(const FFinstance* instance, FFWifiResult* result)
{
FF_UNUSED(instance);
ffStrbufAppendS(&result->error, "Not supported on this platform");
}

View File

@ -0,0 +1,242 @@
#include "wifi.h"
#include "util/windows/unicode.h"
#include <wlanapi.h>
static inline void wrapCloseHandle(HANDLE* handle)
{
if(*handle)
CloseHandle(*handle);
}
static inline void wrapWlanFreeMemory(void* memory)
{
if(*(void**)memory)
WlanFreeMemory(*(void**)memory);
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch"
static void convertIfStateToString(WLAN_INTERFACE_STATE state, FFstrbuf* result)
{
switch (state) {
case wlan_interface_state_not_ready:
ffStrbufAppendS(result, "Not ready");
break;
case wlan_interface_state_connected:
ffStrbufAppendS(result, "Connected");
break;
case wlan_interface_state_ad_hoc_network_formed:
ffStrbufAppendS(result, "First node in a ad hoc network");
break;
case wlan_interface_state_disconnecting:
ffStrbufAppendS(result, "Disconnecting");
break;
case wlan_interface_state_disconnected:
ffStrbufAppendS(result, "Not connected");
break;
case wlan_interface_state_associating:
ffStrbufAppendS(result, "Attempting to associate with a network");
break;
case wlan_interface_state_discovering:
ffStrbufAppendS(result, "Auto configuration is discovering settings for the network");
break;
case wlan_interface_state_authenticating:
ffStrbufAppendS(result, "In process of authenticating");
break;
default:
ffStrbufAppendS(result, "Unknown");
break;
}
}
void ffDetectWifi(const FFinstance* instance, FFWifiResult* result)
{
FF_UNUSED(instance);
DWORD curVersion;
HANDLE __attribute__((__cleanup__(wrapCloseHandle))) hClient = NULL;
if(WlanOpenHandle(1, NULL, &curVersion, &hClient) != ERROR_SUCCESS)
{
ffStrbufAppendS(&result->error, "WlanOpenHandle() failed");
return;
}
WLAN_INTERFACE_INFO_LIST* __attribute__((__cleanup__(wrapWlanFreeMemory))) ifList = NULL;
if(WlanEnumInterfaces(hClient, NULL, &ifList) != ERROR_SUCCESS)
{
ffStrbufAppendS(&result->error, "WlanEnumInterfaces() failed");
return;
}
if(ifList->dwNumberOfItems == 0)
{
ffStrbufAppendS(&result->error, "WlanEnumInterfaces() returns empty result");
return;
}
WLAN_INTERFACE_INFO* ifInfo = (WLAN_INTERFACE_INFO*)&ifList->InterfaceInfo[0];
ffStrbufSetWS(&result->inf.description, ifInfo->strInterfaceDescription);
convertIfStateToString(ifInfo->isState, &result->inf.status);
if(ifInfo->isState != wlan_interface_state_connected)
return;
WLAN_CONNECTION_ATTRIBUTES* __attribute__((__cleanup__(wrapWlanFreeMemory))) connInfo = NULL;
DWORD connectInfoSize = sizeof(WLAN_CONNECTION_ATTRIBUTES);
WLAN_OPCODE_VALUE_TYPE opCode = wlan_opcode_value_type_invalid;
if(WlanQueryInterface(hClient,
&ifInfo->InterfaceGuid,
wlan_intf_opcode_current_connection,
NULL,
&connectInfoSize,
(PVOID*)&connInfo,
&opCode) != ERROR_SUCCESS)
{
ffStrbufAppendS(&result->error, "WlanQueryInterface() failed");
return;
}
convertIfStateToString(connInfo->isState, &result->conn.status);
ffStrbufAppendNS(&result->conn.ssid,
connInfo->wlanAssociationAttributes.dot11Ssid.uSSIDLength,
(const char *)connInfo->wlanAssociationAttributes.dot11Ssid.ucSSID);
for (size_t i = 0; i < sizeof(connInfo->wlanAssociationAttributes.dot11Bssid); i++)
ffStrbufAppendF(&result->conn.macAddress, "%.2X-", connInfo->wlanAssociationAttributes.dot11Bssid[i]);
ffStrbufTrimRight(&result->conn.macAddress, '-');
switch (connInfo->wlanAssociationAttributes.dot11PhyType)
{
case dot11_phy_type_fhss:
ffStrbufAppendS(&result->conn.phyType, "802.11 (FHSS)");
break;
case dot11_phy_type_dsss:
ffStrbufAppendS(&result->conn.phyType, "802.11 (DSSS)");
break;
case dot11_phy_type_irbaseband:
ffStrbufAppendS(&result->conn.phyType, "802.11 (IR)");
break;
case dot11_phy_type_ofdm:
ffStrbufAppendS(&result->conn.phyType, "802.11a");
break;
case dot11_phy_type_hrdsss:
ffStrbufAppendS(&result->conn.phyType, "802.11b");
break;
case dot11_phy_type_erp:
ffStrbufAppendS(&result->conn.phyType, "802.11g");
break;
case dot11_phy_type_ht:
ffStrbufAppendS(&result->conn.phyType, "802.11n (Wi-Fi 4)");
break;
case 8 /*dot11_phy_type_vht*/:
ffStrbufAppendS(&result->conn.phyType, "802.11ac (Wi-Fi 5)");
break;
case 9 /*dot11_phy_type_dmg*/:
ffStrbufAppendS(&result->conn.phyType, "802.11ad (WiGig)");
break;
case 10 /*dot11_phy_type_he*/:
ffStrbufAppendS(&result->conn.phyType, "802.11ax (Wi-Fi 6)");
break;
case 11 /*dot11_phy_type_eht*/:
ffStrbufAppendS(&result->conn.phyType, "802.11be (Wi-Fi 7)");
break;
default:
ffStrbufAppendF(&result->conn.phyType, "Unknown (%u)", (unsigned)connInfo->wlanAssociationAttributes.dot11PhyType);
break;
}
result->conn.signalQuality = connInfo->wlanAssociationAttributes.wlanSignalQuality;
result->conn.rxRate = connInfo->wlanAssociationAttributes.ulRxRate;
result->conn.txRate = connInfo->wlanAssociationAttributes.ulTxRate;
result->security.enabled = connInfo->wlanSecurityAttributes.bSecurityEnabled;
result->security.oneXEnabled = connInfo->wlanSecurityAttributes.bOneXEnabled;
switch (connInfo->wlanSecurityAttributes.dot11AuthAlgorithm)
{
case DOT11_AUTH_ALGO_80211_OPEN:
ffStrbufAppendS(&result->security.authAlgo, "802.11 Open");
break;
case DOT11_AUTH_ALGO_80211_SHARED_KEY:
ffStrbufAppendS(&result->security.authAlgo, "802.11 Shared");
break;
case DOT11_AUTH_ALGO_WPA:
ffStrbufAppendS(&result->security.authAlgo, "WPA");
break;
case DOT11_AUTH_ALGO_WPA_PSK:
ffStrbufAppendS(&result->security.authAlgo, "WPA-PSK");
break;
case DOT11_AUTH_ALGO_WPA_NONE:
ffStrbufAppendS(&result->security.authAlgo, "WPA-None");
break;
case DOT11_AUTH_ALGO_RSNA:
ffStrbufAppendS(&result->security.authAlgo, "RSNA");
break;
case DOT11_AUTH_ALGO_RSNA_PSK:
ffStrbufAppendS(&result->security.authAlgo, "RSNA with PSK");
break;
case 8 /* DOT11_AUTH_ALGO_WPA3 */:
ffStrbufAppendS(&result->security.authAlgo, "WPA3");
break;
case 9 /* DOT11_AUTH_ALGO_WPA3_SAE */:
ffStrbufAppendS(&result->security.authAlgo, "WPA3-SAE");
break;
case 10 /* DOT11_AUTH_ALGO_OWE */:
ffStrbufAppendS(&result->security.authAlgo, "OWE");
break;
case 11 /* DOT11_AUTH_ALGO_WPA3_ENT */:
ffStrbufAppendS(&result->security.authAlgo, "OWE-ENT");
break;
default:
ffStrbufAppendF(&result->security.authAlgo, "Unknown (%u)", (unsigned)connInfo->wlanSecurityAttributes.dot11AuthAlgorithm);
break;
}
switch (connInfo->wlanSecurityAttributes.dot11CipherAlgorithm)
{
case DOT11_CIPHER_ALGO_NONE:
ffStrbufAppendS(&result->security.cipherAlgo, "None");
break;
case DOT11_CIPHER_ALGO_WEP40:
ffStrbufAppendS(&result->security.cipherAlgo, "WEP-40");
break;
case DOT11_CIPHER_ALGO_TKIP:
ffStrbufAppendS(&result->security.cipherAlgo, "TKIP");
break;
case DOT11_CIPHER_ALGO_CCMP:
ffStrbufAppendS(&result->security.cipherAlgo, "CCMP");
break;
case DOT11_CIPHER_ALGO_WEP104:
ffStrbufAppendS(&result->security.cipherAlgo, "WEP-104");
break;
case 0x06 /* DOT11_CIPHER_ALGO_BIP */:
ffStrbufAppendS(&result->security.cipherAlgo, "BIP-CMAC-128");
break;
case 0x08 /* DOT11_CIPHER_ALGO_GCMP */:
ffStrbufAppendS(&result->security.cipherAlgo, "GCMP-128");
break;
case 0x09 /* DOT11_CIPHER_ALGO_GCMP_256 */:
ffStrbufAppendS(&result->security.cipherAlgo, "GCMP-256");
break;
case 0x0a /* DOT11_CIPHER_ALGO_CCMP_256 */:
ffStrbufAppendS(&result->security.cipherAlgo, "CCMP-256");
break;
case 0x0b /* DOT11_CIPHER_ALGO_BIP_GMAC_128 */:
ffStrbufAppendS(&result->security.cipherAlgo, "BIP-GMAC-128");
break;
case 0x0c /* DOT11_CIPHER_ALGO_BIP_GMAC_256 */:
ffStrbufAppendS(&result->security.cipherAlgo, "BIP-GMAC-256");
break;
case 0x0d /* DOT11_CIPHER_ALGO_BIP_CMAC_256 */:
ffStrbufAppendS(&result->security.cipherAlgo, "BIP-CMAC-256");
break;
case DOT11_CIPHER_ALGO_WEP:
ffStrbufAppendS(&result->security.cipherAlgo, "WEP");
break;
default:
ffStrbufAppendF(&result->security.cipherAlgo, "Unknown (%u)", (unsigned)connInfo->wlanSecurityAttributes.dot11CipherAlgorithm);
break;
}
}
#pragma GCC diagnostic pop

View File

@ -350,6 +350,24 @@ static inline void printCommandHelp(const char* command)
"Public IP address"
);
}
else if(strcasecmp(command, "wifi-format") == 0)
{
constructAndPrintCommandHelpFormat("wifi", "{4} - {6}", 3,
"Interface description",
"Interface status",
"Connection status",
"Connection SSID",
"Connection mac address",
"Connection PHY type",
"Connection signal quality (percentage)",
"Connection RX rate",
"Connection TX rate",
"Security enabled",
"Security 802.1X enabled",
"Security auth algorithm",
"Security cipher algorithm"
);
}
else if(strcasecmp(command, "player-format") == 0)
{
constructAndPrintCommandHelpFormat("player", "{}", 4,
@ -1041,6 +1059,7 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con
else if(optionParseModuleArgs(key, value, "shell", &instance->config.shell)) {}
else if(optionParseModuleArgs(key, value, "resolution", &instance->config.resolution)) {}
else if(optionParseModuleArgs(key, value, "de", &instance->config.de)) {}
else if(optionParseModuleArgs(key, value, "wifi", &instance->config.wifi)) {}
else if(optionParseModuleArgs(key, value, "wm", &instance->config.wm)) {}
else if(optionParseModuleArgs(key, value, "wm-theme", &instance->config.wmTheme)) {}
else if(optionParseModuleArgs(key, value, "theme", &instance->config.theme)) {}
@ -1310,6 +1329,8 @@ static void parseStructureCommand(FFinstance* instance, FFdata* data, const char
ffPrintLocalIp(instance);
else if(strcasecmp(line, "publicip") == 0)
ffPrintPublicIp(instance);
else if(strcasecmp(line, "wifi") == 0)
ffPrintWifi(instance);
else if(strcasecmp(line, "weather") == 0)
ffPrintWeather(instance);
else if(strcasecmp(line, "player") == 0)

View File

@ -108,6 +108,7 @@ typedef struct FFconfig
FFModuleArgs shell;
FFModuleArgs resolution;
FFModuleArgs de;
FFModuleArgs wifi;
FFModuleArgs wm;
FFModuleArgs wmTheme;
FFModuleArgs theme;
@ -293,6 +294,7 @@ void ffPrintTime(FFinstance* instance);
void ffPrintLocalIp(FFinstance* instance);
void ffPrintPublicIp(FFinstance* instance);
void ffPrintWeather(FFinstance* instance);
void ffPrintWifi(FFinstance* instance);
void ffPrintColors(FFinstance* instance);
void ffPrintVulkan(FFinstance* instance);
void ffPrintOpenGL(FFinstance* instance);

View File

@ -50,6 +50,7 @@ int main(int argc, char** argv)
//ffPrintSong(&instance);
//ffPrintLocalIp(&instance);
//ffPrintPublicIp(&instance);
//ffPrintWifi(&instance);
//ffPrintCPUUsage(&instance);
ffPrintLocale(&instance);
//ffPrintDateTime(&instance);

79
src/modules/wifi.c Normal file
View File

@ -0,0 +1,79 @@
#include "fastfetch.h"
#include "common/printing.h"
#include "detection/wifi/wifi.h"
#define FF_WIFI_MODULE_NAME "Wifi"
#define FF_WIFI_NUM_FORMAT_ARGS 13
void ffPrintWifi(FFinstance* instance)
{
FFWifiResult result;
ffStrbufInit(&result.inf.description);
ffStrbufInit(&result.inf.status);
ffStrbufInit(&result.conn.status);
ffStrbufInit(&result.conn.ssid);
ffStrbufInit(&result.conn.macAddress);
ffStrbufInit(&result.conn.phyType);
result.conn.signalQuality = 0.0/0.0;
result.conn.rxRate = 0.0/0.0;
result.conn.txRate = 0.0/0.0;
result.security.enabled = false;
result.security.oneXEnabled = false;
ffStrbufInit(&result.security.authAlgo);
ffStrbufInit(&result.security.cipherAlgo);
ffStrbufInit(&result.error);
ffDetectWifi(instance, &result);
if(!result.error.length)
{
if(instance->config.wifi.outputFormat.length == 0)
{
ffPrintLogoAndKey(instance, FF_WIFI_MODULE_NAME, 0, &instance->config.wifi.key);
if(result.conn.ssid.length)
{
printf("%s - %s", result.conn.ssid.chars, result.conn.phyType.chars);
if(!result.security.enabled)
puts(" - insecure");
else
putchar('\n');
}
else
{
puts(result.inf.status.chars);
}
}
else
{
ffPrintFormat(instance, FF_WIFI_MODULE_NAME, 0, &instance->config.wifi, FF_WIFI_NUM_FORMAT_ARGS, (FFformatarg[]){
{FF_FORMAT_ARG_TYPE_STRBUF, &result.inf.description},
{FF_FORMAT_ARG_TYPE_STRBUF, &result.inf.status},
{FF_FORMAT_ARG_TYPE_STRBUF, &result.conn.status},
{FF_FORMAT_ARG_TYPE_STRBUF, &result.conn.ssid},
{FF_FORMAT_ARG_TYPE_STRBUF, &result.conn.macAddress},
{FF_FORMAT_ARG_TYPE_STRBUF, &result.conn.phyType},
{FF_FORMAT_ARG_TYPE_DOUBLE, &result.conn.signalQuality},
{FF_FORMAT_ARG_TYPE_DOUBLE, &result.conn.rxRate},
{FF_FORMAT_ARG_TYPE_DOUBLE, &result.conn.txRate},
{FF_FORMAT_ARG_TYPE_BOOL, &result.security.enabled},
{FF_FORMAT_ARG_TYPE_BOOL, &result.security.oneXEnabled},
{FF_FORMAT_ARG_TYPE_STRBUF, &result.security.authAlgo},
{FF_FORMAT_ARG_TYPE_STRBUF, &result.security.cipherAlgo},
});
}
}
else
{
ffPrintError(instance, FF_WIFI_MODULE_NAME, 0, &instance->config.wmTheme, "%*s", result.error.length, result.error.chars);
}
ffStrbufDestroy(&result.inf.description);
ffStrbufDestroy(&result.inf.status);
ffStrbufDestroy(&result.conn.status);
ffStrbufDestroy(&result.conn.ssid);
ffStrbufDestroy(&result.conn.macAddress);
ffStrbufDestroy(&result.conn.phyType);
ffStrbufDestroy(&result.security.authAlgo);
ffStrbufDestroy(&result.security.cipherAlgo);
ffStrbufDestroy(&result.error);
}