Skip to content

Commit 40ab735

Browse files
authored
LocalIp: support get interface flags (#1315)
1 parent 716bfe7 commit 40ab735

File tree

9 files changed

+143
-2
lines changed

9 files changed

+143
-2
lines changed

.codespellrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
check-filenames =
33
builtin = clear,rare,usage,informal
44
skip = */.git,*/cmake-build-*,*/.idea,*/completions,*/presets,*/screenshots,*/tests,*/3rdparty,*/logo/ascii
5-
ignore-words-list = iterm,compiletime,unknwn,pengwin,siduction,master,sur,doas,conexant
5+
ignore-words-list = iterm,compiletime,unknwn,pengwin,siduction,master,slave,sur,doas,conexant

completions/fastfetch.bash

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ __fastfetch_completion()
183183
"--display-precise-refresh-rate"
184184
"--localip-show-ipv4"
185185
"--localip-show-ipv6"
186+
"--localip-show-flags"
186187
"--localip-show-loop"
187188
"--localip-name-prefix"
188189
"--localip-compact-type"

doc/json_schema.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1703,6 +1703,11 @@
17031703
"type": "boolean",
17041704
"default": false
17051705
},
1706+
"showFlags": {
1707+
"description": "Show the interface's flags",
1708+
"type": "boolean",
1709+
"default": false
1710+
},
17061711
"compact": {
17071712
"description": "Show all IPs in one line",
17081713
"type": "boolean",

src/data/help.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,6 +1231,15 @@
12311231
"default": false
12321232
}
12331233
},
1234+
{
1235+
"long": "localip-show-flags",
1236+
"desc": "Show net interface flags in local ip module",
1237+
"arg": {
1238+
"type": "bool",
1239+
"optional": true,
1240+
"default": false
1241+
}
1242+
},
12341243
{
12351244
"long": "localip-compact",
12361245
"desc": "Show all IPs in one line",

src/detection/localip/localip.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,29 @@ typedef struct FFLocalIpResult
88
FFstrbuf ipv4;
99
FFstrbuf ipv6;
1010
FFstrbuf mac;
11+
FFstrbuf flags;
1112
int32_t mtu;
1213
int32_t speed;
1314
bool defaultRoute;
1415
} FFLocalIpResult;
1516

17+
typedef struct NIFlag
18+
{
19+
int flag;
20+
const char *name;
21+
} NIFlag;
22+
23+
static inline void writeNIFlagsToStrBuf(FFstrbuf *buf, int flag, const NIFlag names[])
24+
{
25+
for (const NIFlag *nf = names; nf->name != NULL && flag != 0; ++nf)
26+
{
27+
if (flag & nf->flag) {
28+
if (nf - names != 0)
29+
ffStrbufAppendC(buf, ',');
30+
ffStrbufAppendS(buf, nf->name);
31+
flag &= ~nf->flag;
32+
}
33+
}
34+
}
35+
1636
const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results);

src/detection/localip/localip_linux.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#ifdef __linux__
1616
#include <linux/ethtool.h>
1717
#include <linux/sockios.h>
18+
#include <linux/if.h>
1819
#endif
1920

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

31+
static const NIFlag niFlags[] = {
32+
{ IFF_UP, "UP" },
33+
{ IFF_BROADCAST, "BROADCAST" },
34+
{ IFF_DEBUG, "DEBUG" },
35+
{ IFF_LOOPBACK, "LOOPBACK" },
36+
{ IFF_POINTOPOINT, "POINTOPOINT" },
37+
{ IFF_RUNNING, "RUNNING" },
38+
{ IFF_NOARP, "NOARP" },
39+
{ IFF_PROMISC, "PROMISC" },
40+
{ IFF_ALLMULTI, "ALLMULTI" },
41+
{ IFF_MULTICAST, "MULTICAST" },
42+
#if defined(__linux__) || defined(__APPLE__) || defined(__sun)
43+
{ IFF_NOTRAILERS, "NOTRAILERS" },
44+
#endif
45+
#ifdef __linux__
46+
{ IFF_MASTER, "MASTER" },
47+
{ IFF_SLAVE, "SLAVE" },
48+
{ IFF_PORTSEL, "PORTSEL" },
49+
{ IFF_AUTOMEDIA, "AUTOMEDIA" },
50+
{ IFF_DYNAMIC, "DYNAMIC" },
51+
{ IFF_LOWER_UP, "LOWER_UP" },
52+
{ IFF_DORMANT, "DORMANT" },
53+
{ IFF_ECHO, "ECHO" },
54+
#endif
55+
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__OpenBSD__)
56+
{ IFF_OACTIVE, "OACTIVE" },
57+
{ IFF_SIMPLEX, "SIMPLEX" },
58+
{ IFF_LINK0, "LINK0" },
59+
{ IFF_LINK1, "LINK1" },
60+
{ IFF_LINK2, "LINK2" },
61+
#endif
62+
#if defined(__FreeBSD__) || defined(__APPLE__)
63+
{ IFF_ALTPHYS, "ALTPHYS" },
64+
#endif
65+
#ifdef __FreeBSD__
66+
{ IFF_CANTCONFIG, "CANTCONFIG" },
67+
#endif
68+
// sentinel
69+
{ 0, NULL }
70+
};
71+
3072
static void addNewIp(FFlist* list, const char* name, const char* addr, int type, bool defaultRoute, bool firstOnly)
3173
{
3274
FFLocalIpResult* ip = NULL;
@@ -44,6 +86,7 @@ static void addNewIp(FFlist* list, const char* name, const char* addr, int type,
4486
ffStrbufInit(&ip->ipv4);
4587
ffStrbufInit(&ip->ipv6);
4688
ffStrbufInit(&ip->mac);
89+
ffStrbufInit(&ip->flags);
4790
ip->defaultRoute = defaultRoute;
4891
ip->mtu = -1;
4992
ip->speed = -1;
@@ -96,6 +139,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
96139
if (options->namePrefix.length && strncmp(ifa->ifa_name, options->namePrefix.chars, options->namePrefix.length) != 0)
97140
continue;
98141

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

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

144189
addNewIp(results, ifa->ifa_name, addressBuffer, AF_INET6, isDefaultRoute, !(options->showType & FF_LOCALIP_TYPE_ALL_IPS_BIT));
190+
newIP = true;
145191
}
146192
#if __FreeBSD__ || __OpenBSD__ || __APPLE__
147193
else if (ifa->ifa_addr->sa_family == AF_LINK)
@@ -154,6 +200,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
154200
snprintf(addressBuffer, sizeof(addressBuffer), "%02x:%02x:%02x:%02x:%02x:%02x",
155201
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
156202
addNewIp(results, ifa->ifa_name, addressBuffer, -1, isDefaultRoute, false);
203+
newIP = true;
157204
}
158205
#else
159206
else if (ifa->ifa_addr->sa_family == AF_PACKET)
@@ -166,8 +213,16 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
166213
snprintf(addressBuffer, sizeof(addressBuffer), "%02x:%02x:%02x:%02x:%02x:%02x",
167214
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
168215
addNewIp(results, ifa->ifa_name, addressBuffer, -1, isDefaultRoute, false);
216+
newIP = true;
169217
}
170218
#endif
219+
220+
if (newIP)
221+
{
222+
FFLocalIpResult* result = FF_LIST_GET(FFLocalIpResult, *results, results->length - 1);
223+
if (options->showType & FF_LOCALIP_TYPE_FLAGS_BIT)
224+
writeNIFlagsToStrBuf(&result->flags, (int)ifa->ifa_flags, niFlags);
225+
}
171226
}
172227

173228
if (ifAddrStruct) freeifaddrs(ifAddrStruct);

src/detection/localip/localip_windows.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,21 @@
66
#include "util/windows/unicode.h"
77
#include "localip.h"
88

9+
static const NIFlag niFlags[] = {
10+
{ IP_ADAPTER_DDNS_ENABLED, "DDNS_ENABLED" },
11+
{ IP_ADAPTER_REGISTER_ADAPTER_SUFFIX, "REGISTER_ADAPTER_SUFFIX" },
12+
{ IP_ADAPTER_DHCP_ENABLED, "DHCP_ENABLED" },
13+
{ IP_ADAPTER_RECEIVE_ONLY, "RECEIVE_ONLY" },
14+
{ IP_ADAPTER_NO_MULTICAST, "NO_MULTICAST" },
15+
{ IP_ADAPTER_IPV6_OTHER_STATEFUL_CONFIG, "IPV6_OTHER_STATEFUL_CONFIG" },
16+
{ IP_ADAPTER_NETBIOS_OVER_TCPIP_ENABLED, "NETBIOS_OVER_TCPIP_ENABLED" },
17+
{ IP_ADAPTER_IPV4_ENABLED, "IPV4_ENABLED" },
18+
{ IP_ADAPTER_IPV6_ENABLED, "IPV6_ENABLED" },
19+
{ IP_ADAPTER_IPV6_MANAGE_ADDRESS_CONFIG, "IPV6_MANAGE_ADDRESS_CONFIG" },
20+
// sentinel
21+
{ 0, NULL }
22+
};
23+
924
static void addNewIp(FFlist* list, const char* name, const char* addr, int type, bool newIp, bool defaultRoute)
1025
{
1126
FFLocalIpResult* ip = NULL;
@@ -17,6 +32,7 @@ static void addNewIp(FFlist* list, const char* name, const char* addr, int type,
1732
ffStrbufInit(&ip->ipv4);
1833
ffStrbufInit(&ip->ipv6);
1934
ffStrbufInit(&ip->mac);
35+
ffStrbufInit(&ip->flags);
2036
ip->defaultRoute = defaultRoute;
2137
ip->speed = -1;
2238
ip->mtu = -1;
@@ -157,6 +173,8 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
157173
result->speed = (int32_t) (adapter->ReceiveLinkSpeed / 1000);
158174
if (options->showType & FF_LOCALIP_TYPE_MTU_BIT)
159175
result->mtu = (int32_t) adapter->Mtu;
176+
if (options->showType & FF_LOCALIP_TYPE_FLAGS_BIT)
177+
writeNIFlagsToStrBuf(&result->flags, (int)adapter->Flags, niFlags);
160178
}
161179
}
162180

src/modules/localip/localip.c

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include "util/stringUtils.h"
66

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

1111
static int sortIps(const FFLocalIpResult* left, const FFLocalIpResult* right)
@@ -77,6 +77,12 @@ static void printIp(FFLocalIpResult* ip, bool markDefaultRoute)
7777
putchar(']');
7878
flag = true;
7979
}
80+
if (ip->flags.length) {
81+
if (flag) fputs(" <", stdout);
82+
ffStrbufWriteTo(&ip->flags, stdout);
83+
putchar('>');
84+
flag = true;
85+
}
8086
if (markDefaultRoute && flag && ip->defaultRoute)
8187
fputs(" *", stdout);
8288
}
@@ -151,6 +157,7 @@ void ffPrintLocalIp(FFLocalIpOptions* options)
151157
FF_FORMAT_ARG(ip->defaultRoute, "is-default-route"),
152158
FF_FORMAT_ARG(ip->mtu, "mtu"),
153159
FF_FORMAT_ARG(speedStr, "speed"),
160+
FF_FORMAT_ARG(ip->flags, "flags"),
154161
}));
155162
}
156163
++index;
@@ -163,6 +170,7 @@ void ffPrintLocalIp(FFLocalIpOptions* options)
163170
ffStrbufDestroy(&ip->ipv4);
164171
ffStrbufDestroy(&ip->ipv6);
165172
ffStrbufDestroy(&ip->mac);
173+
ffStrbufDestroy(&ip->flags);
166174
}
167175
}
168176

@@ -236,6 +244,15 @@ bool ffParseLocalIpCommandOptions(FFLocalIpOptions* options, const char* key, co
236244
return true;
237245
}
238246

247+
if (ffStrEqualsIgnCase(subKey, "show-flags"))
248+
{
249+
if (ffOptionParseBoolean(value))
250+
options->showType |= FF_LOCALIP_TYPE_FLAGS_BIT;
251+
else
252+
options->showType &= ~FF_LOCALIP_TYPE_FLAGS_BIT;
253+
return true;
254+
}
255+
239256
if(ffStrEqualsIgnCase(subKey, "compact"))
240257
{
241258
if (ffOptionParseBoolean(value))
@@ -348,6 +365,15 @@ void ffParseLocalIpJsonObject(FFLocalIpOptions* options, yyjson_val* module)
348365
continue;
349366
}
350367

368+
if (ffStrEqualsIgnCase(key, "showFlags"))
369+
{
370+
if (yyjson_get_bool(val))
371+
options->showType |= FF_LOCALIP_TYPE_FLAGS_BIT;
372+
else
373+
options->showType &= ~FF_LOCALIP_TYPE_FLAGS_BIT;
374+
continue;
375+
}
376+
351377
if (ffStrEqualsIgnCase(key, "compact"))
352378
{
353379
if (yyjson_get_bool(val))
@@ -415,6 +441,9 @@ void ffGenerateLocalIpJsonConfig(FFLocalIpOptions* options, yyjson_mut_doc* doc,
415441
if (options->showType & FF_LOCALIP_TYPE_SPEED_BIT)
416442
yyjson_mut_obj_add_bool(doc, module, "showSpeed", true);
417443

444+
if (options->showType & FF_LOCALIP_TYPE_FLAGS_BIT)
445+
yyjson_mut_obj_add_bool(doc, module, "showFlags", true);
446+
418447
if (options->showType & FF_LOCALIP_TYPE_COMPACT_BIT)
419448
yyjson_mut_obj_add_bool(doc, module, "compact", true);
420449

@@ -452,6 +481,7 @@ void ffGenerateLocalIpJsonResult(FF_MAYBE_UNUSED FFLocalIpOptions* options, yyjs
452481
yyjson_mut_obj_add_strbuf(doc, obj, "name", &ip->name);
453482
yyjson_mut_obj_add_int(doc, obj, "mtu", ip->mtu);
454483
yyjson_mut_obj_add_int(doc, obj, "speed", ip->speed);
484+
yyjson_mut_obj_add_strbuf(doc, obj, "flags", &ip->flags);
455485
}
456486

457487
FF_LIST_FOR_EACH(FFLocalIpResult, ip, results)
@@ -460,6 +490,7 @@ void ffGenerateLocalIpJsonResult(FF_MAYBE_UNUSED FFLocalIpOptions* options, yyjs
460490
ffStrbufDestroy(&ip->ipv4);
461491
ffStrbufDestroy(&ip->ipv6);
462492
ffStrbufDestroy(&ip->mac);
493+
ffStrbufDestroy(&ip->flags);
463494
}
464495
}
465496

@@ -473,6 +504,7 @@ void ffPrintLocalIpHelpFormat(void)
473504
"Is default route - is-default-route",
474505
"MTU size in bytes - mtu",
475506
"Link speed (formatted) - speed",
507+
"Interface flags - flags",
476508
}));
477509
}
478510

src/modules/localip/option.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ typedef enum FFLocalIpType
1414
FF_LOCALIP_TYPE_PREFIX_LEN_BIT = 1 << 4,
1515
FF_LOCALIP_TYPE_MTU_BIT = 1 << 5,
1616
FF_LOCALIP_TYPE_SPEED_BIT = 1 << 6,
17+
FF_LOCALIP_TYPE_FLAGS_BIT = 1 << 7,
1718

1819
FF_LOCALIP_TYPE_COMPACT_BIT = 1 << 10,
1920
FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT = 1 << 11,

0 commit comments

Comments
 (0)