Skip to content

Commit

Permalink
LocalIp: support get interface flags (#1315)
Browse files Browse the repository at this point in the history
  • Loading branch information
apocelipes authored Oct 5, 2024
1 parent 716bfe7 commit 40ab735
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .codespellrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
check-filenames =
builtin = clear,rare,usage,informal
skip = */.git,*/cmake-build-*,*/.idea,*/completions,*/presets,*/screenshots,*/tests,*/3rdparty,*/logo/ascii
ignore-words-list = iterm,compiletime,unknwn,pengwin,siduction,master,sur,doas,conexant
ignore-words-list = iterm,compiletime,unknwn,pengwin,siduction,master,slave,sur,doas,conexant
1 change: 1 addition & 0 deletions completions/fastfetch.bash
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ __fastfetch_completion()
"--display-precise-refresh-rate"
"--localip-show-ipv4"
"--localip-show-ipv6"
"--localip-show-flags"
"--localip-show-loop"
"--localip-name-prefix"
"--localip-compact-type"
Expand Down
5 changes: 5 additions & 0 deletions doc/json_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1703,6 +1703,11 @@
"type": "boolean",
"default": false
},
"showFlags": {
"description": "Show the interface's flags",
"type": "boolean",
"default": false
},
"compact": {
"description": "Show all IPs in one line",
"type": "boolean",
Expand Down
9 changes: 9 additions & 0 deletions src/data/help.json
Original file line number Diff line number Diff line change
Expand Up @@ -1231,6 +1231,15 @@
"default": false
}
},
{
"long": "localip-show-flags",
"desc": "Show net interface flags in local ip module",
"arg": {
"type": "bool",
"optional": true,
"default": false
}
},
{
"long": "localip-compact",
"desc": "Show all IPs in one line",
Expand Down
20 changes: 20 additions & 0 deletions src/detection/localip/localip.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,29 @@ typedef struct FFLocalIpResult
FFstrbuf ipv4;
FFstrbuf ipv6;
FFstrbuf mac;
FFstrbuf flags;
int32_t mtu;
int32_t speed;
bool defaultRoute;
} FFLocalIpResult;

typedef struct NIFlag
{
int flag;
const char *name;
} NIFlag;

static inline void writeNIFlagsToStrBuf(FFstrbuf *buf, int flag, const NIFlag names[])
{
for (const NIFlag *nf = names; nf->name != NULL && flag != 0; ++nf)
{
if (flag & nf->flag) {
if (nf - names != 0)
ffStrbufAppendC(buf, ',');
ffStrbufAppendS(buf, nf->name);
flag &= ~nf->flag;
}
}
}

const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results);
55 changes: 55 additions & 0 deletions src/detection/localip/localip_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#ifdef __linux__
#include <linux/ethtool.h>
#include <linux/sockios.h>
#include <linux/if.h>
#endif

#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
Expand All @@ -27,6 +28,47 @@
#include <sys/sockio.h>
#endif

static const NIFlag niFlags[] = {
{ IFF_UP, "UP" },
{ IFF_BROADCAST, "BROADCAST" },
{ IFF_DEBUG, "DEBUG" },
{ IFF_LOOPBACK, "LOOPBACK" },
{ IFF_POINTOPOINT, "POINTOPOINT" },
{ IFF_RUNNING, "RUNNING" },
{ IFF_NOARP, "NOARP" },
{ IFF_PROMISC, "PROMISC" },
{ IFF_ALLMULTI, "ALLMULTI" },
{ IFF_MULTICAST, "MULTICAST" },
#if defined(__linux__) || defined(__APPLE__) || defined(__sun)
{ IFF_NOTRAILERS, "NOTRAILERS" },
#endif
#ifdef __linux__
{ IFF_MASTER, "MASTER" },
{ IFF_SLAVE, "SLAVE" },
{ IFF_PORTSEL, "PORTSEL" },
{ IFF_AUTOMEDIA, "AUTOMEDIA" },
{ IFF_DYNAMIC, "DYNAMIC" },
{ IFF_LOWER_UP, "LOWER_UP" },
{ IFF_DORMANT, "DORMANT" },
{ IFF_ECHO, "ECHO" },
#endif
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__OpenBSD__)
{ IFF_OACTIVE, "OACTIVE" },
{ IFF_SIMPLEX, "SIMPLEX" },
{ IFF_LINK0, "LINK0" },
{ IFF_LINK1, "LINK1" },
{ IFF_LINK2, "LINK2" },
#endif
#if defined(__FreeBSD__) || defined(__APPLE__)
{ IFF_ALTPHYS, "ALTPHYS" },
#endif
#ifdef __FreeBSD__
{ IFF_CANTCONFIG, "CANTCONFIG" },
#endif
// sentinel
{ 0, NULL }
};

static void addNewIp(FFlist* list, const char* name, const char* addr, int type, bool defaultRoute, bool firstOnly)
{
FFLocalIpResult* ip = NULL;
Expand All @@ -44,6 +86,7 @@ static void addNewIp(FFlist* list, const char* name, const char* addr, int type,
ffStrbufInit(&ip->ipv4);
ffStrbufInit(&ip->ipv6);
ffStrbufInit(&ip->mac);
ffStrbufInit(&ip->flags);
ip->defaultRoute = defaultRoute;
ip->mtu = -1;
ip->speed = -1;
Expand Down Expand Up @@ -96,6 +139,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
if (options->namePrefix.length && strncmp(ifa->ifa_name, options->namePrefix.chars, options->namePrefix.length) != 0)
continue;

bool newIP = false;
if (ifa->ifa_addr->sa_family == AF_INET)
{
if (!(options->showType & FF_LOCALIP_TYPE_IPV4_BIT))
Expand All @@ -117,6 +161,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
}

addNewIp(results, ifa->ifa_name, addressBuffer, AF_INET, isDefaultRoute, !(options->showType & FF_LOCALIP_TYPE_ALL_IPS_BIT));
newIP = true;
}
else if (ifa->ifa_addr->sa_family == AF_INET6)
{
Expand All @@ -142,6 +187,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
}

addNewIp(results, ifa->ifa_name, addressBuffer, AF_INET6, isDefaultRoute, !(options->showType & FF_LOCALIP_TYPE_ALL_IPS_BIT));
newIP = true;
}
#if __FreeBSD__ || __OpenBSD__ || __APPLE__
else if (ifa->ifa_addr->sa_family == AF_LINK)
Expand All @@ -154,6 +200,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
snprintf(addressBuffer, sizeof(addressBuffer), "%02x:%02x:%02x:%02x:%02x:%02x",
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
addNewIp(results, ifa->ifa_name, addressBuffer, -1, isDefaultRoute, false);
newIP = true;
}
#else
else if (ifa->ifa_addr->sa_family == AF_PACKET)
Expand All @@ -166,8 +213,16 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
snprintf(addressBuffer, sizeof(addressBuffer), "%02x:%02x:%02x:%02x:%02x:%02x",
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
addNewIp(results, ifa->ifa_name, addressBuffer, -1, isDefaultRoute, false);
newIP = true;
}
#endif

if (newIP)
{
FFLocalIpResult* result = FF_LIST_GET(FFLocalIpResult, *results, results->length - 1);
if (options->showType & FF_LOCALIP_TYPE_FLAGS_BIT)
writeNIFlagsToStrBuf(&result->flags, (int)ifa->ifa_flags, niFlags);
}
}

if (ifAddrStruct) freeifaddrs(ifAddrStruct);
Expand Down
18 changes: 18 additions & 0 deletions src/detection/localip/localip_windows.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@
#include "util/windows/unicode.h"
#include "localip.h"

static const NIFlag niFlags[] = {
{ IP_ADAPTER_DDNS_ENABLED, "DDNS_ENABLED" },
{ IP_ADAPTER_REGISTER_ADAPTER_SUFFIX, "REGISTER_ADAPTER_SUFFIX" },
{ IP_ADAPTER_DHCP_ENABLED, "DHCP_ENABLED" },
{ IP_ADAPTER_RECEIVE_ONLY, "RECEIVE_ONLY" },
{ IP_ADAPTER_NO_MULTICAST, "NO_MULTICAST" },
{ IP_ADAPTER_IPV6_OTHER_STATEFUL_CONFIG, "IPV6_OTHER_STATEFUL_CONFIG" },
{ IP_ADAPTER_NETBIOS_OVER_TCPIP_ENABLED, "NETBIOS_OVER_TCPIP_ENABLED" },
{ IP_ADAPTER_IPV4_ENABLED, "IPV4_ENABLED" },
{ IP_ADAPTER_IPV6_ENABLED, "IPV6_ENABLED" },
{ IP_ADAPTER_IPV6_MANAGE_ADDRESS_CONFIG, "IPV6_MANAGE_ADDRESS_CONFIG" },
// sentinel
{ 0, NULL }
};

static void addNewIp(FFlist* list, const char* name, const char* addr, int type, bool newIp, bool defaultRoute)
{
FFLocalIpResult* ip = NULL;
Expand All @@ -17,6 +32,7 @@ static void addNewIp(FFlist* list, const char* name, const char* addr, int type,
ffStrbufInit(&ip->ipv4);
ffStrbufInit(&ip->ipv6);
ffStrbufInit(&ip->mac);
ffStrbufInit(&ip->flags);
ip->defaultRoute = defaultRoute;
ip->speed = -1;
ip->mtu = -1;
Expand Down Expand Up @@ -157,6 +173,8 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
result->speed = (int32_t) (adapter->ReceiveLinkSpeed / 1000);
if (options->showType & FF_LOCALIP_TYPE_MTU_BIT)
result->mtu = (int32_t) adapter->Mtu;
if (options->showType & FF_LOCALIP_TYPE_FLAGS_BIT)
writeNIFlagsToStrBuf(&result->flags, (int)adapter->Flags, niFlags);
}
}

Expand Down
34 changes: 33 additions & 1 deletion src/modules/localip/localip.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "util/stringUtils.h"

#define FF_LOCALIP_DISPLAY_NAME "Local IP"
#define FF_LOCALIP_NUM_FORMAT_ARGS 7
#define FF_LOCALIP_NUM_FORMAT_ARGS 8
#pragma GCC diagnostic ignored "-Wsign-conversion"

static int sortIps(const FFLocalIpResult* left, const FFLocalIpResult* right)
Expand Down Expand Up @@ -77,6 +77,12 @@ static void printIp(FFLocalIpResult* ip, bool markDefaultRoute)
putchar(']');
flag = true;
}
if (ip->flags.length) {
if (flag) fputs(" <", stdout);
ffStrbufWriteTo(&ip->flags, stdout);
putchar('>');
flag = true;
}
if (markDefaultRoute && flag && ip->defaultRoute)
fputs(" *", stdout);
}
Expand Down Expand Up @@ -151,6 +157,7 @@ void ffPrintLocalIp(FFLocalIpOptions* options)
FF_FORMAT_ARG(ip->defaultRoute, "is-default-route"),
FF_FORMAT_ARG(ip->mtu, "mtu"),
FF_FORMAT_ARG(speedStr, "speed"),
FF_FORMAT_ARG(ip->flags, "flags"),
}));
}
++index;
Expand All @@ -163,6 +170,7 @@ void ffPrintLocalIp(FFLocalIpOptions* options)
ffStrbufDestroy(&ip->ipv4);
ffStrbufDestroy(&ip->ipv6);
ffStrbufDestroy(&ip->mac);
ffStrbufDestroy(&ip->flags);
}
}

Expand Down Expand Up @@ -236,6 +244,15 @@ bool ffParseLocalIpCommandOptions(FFLocalIpOptions* options, const char* key, co
return true;
}

if (ffStrEqualsIgnCase(subKey, "show-flags"))
{
if (ffOptionParseBoolean(value))
options->showType |= FF_LOCALIP_TYPE_FLAGS_BIT;
else
options->showType &= ~FF_LOCALIP_TYPE_FLAGS_BIT;
return true;
}

if(ffStrEqualsIgnCase(subKey, "compact"))
{
if (ffOptionParseBoolean(value))
Expand Down Expand Up @@ -348,6 +365,15 @@ void ffParseLocalIpJsonObject(FFLocalIpOptions* options, yyjson_val* module)
continue;
}

if (ffStrEqualsIgnCase(key, "showFlags"))
{
if (yyjson_get_bool(val))
options->showType |= FF_LOCALIP_TYPE_FLAGS_BIT;
else
options->showType &= ~FF_LOCALIP_TYPE_FLAGS_BIT;
continue;
}

if (ffStrEqualsIgnCase(key, "compact"))
{
if (yyjson_get_bool(val))
Expand Down Expand Up @@ -415,6 +441,9 @@ void ffGenerateLocalIpJsonConfig(FFLocalIpOptions* options, yyjson_mut_doc* doc,
if (options->showType & FF_LOCALIP_TYPE_SPEED_BIT)
yyjson_mut_obj_add_bool(doc, module, "showSpeed", true);

if (options->showType & FF_LOCALIP_TYPE_FLAGS_BIT)
yyjson_mut_obj_add_bool(doc, module, "showFlags", true);

if (options->showType & FF_LOCALIP_TYPE_COMPACT_BIT)
yyjson_mut_obj_add_bool(doc, module, "compact", true);

Expand Down Expand Up @@ -452,6 +481,7 @@ void ffGenerateLocalIpJsonResult(FF_MAYBE_UNUSED FFLocalIpOptions* options, yyjs
yyjson_mut_obj_add_strbuf(doc, obj, "name", &ip->name);
yyjson_mut_obj_add_int(doc, obj, "mtu", ip->mtu);
yyjson_mut_obj_add_int(doc, obj, "speed", ip->speed);
yyjson_mut_obj_add_strbuf(doc, obj, "flags", &ip->flags);
}

FF_LIST_FOR_EACH(FFLocalIpResult, ip, results)
Expand All @@ -460,6 +490,7 @@ void ffGenerateLocalIpJsonResult(FF_MAYBE_UNUSED FFLocalIpOptions* options, yyjs
ffStrbufDestroy(&ip->ipv4);
ffStrbufDestroy(&ip->ipv6);
ffStrbufDestroy(&ip->mac);
ffStrbufDestroy(&ip->flags);
}
}

Expand All @@ -473,6 +504,7 @@ void ffPrintLocalIpHelpFormat(void)
"Is default route - is-default-route",
"MTU size in bytes - mtu",
"Link speed (formatted) - speed",
"Interface flags - flags",
}));
}

Expand Down
1 change: 1 addition & 0 deletions src/modules/localip/option.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ typedef enum FFLocalIpType
FF_LOCALIP_TYPE_PREFIX_LEN_BIT = 1 << 4,
FF_LOCALIP_TYPE_MTU_BIT = 1 << 5,
FF_LOCALIP_TYPE_SPEED_BIT = 1 << 6,
FF_LOCALIP_TYPE_FLAGS_BIT = 1 << 7,

FF_LOCALIP_TYPE_COMPACT_BIT = 1 << 10,
FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT = 1 << 11,
Expand Down

0 comments on commit 40ab735

Please sign in to comment.