Skip to content

Commit a84c4dc

Browse files
committed
Netif: refactor API for dual-stack route detection
Unifies IPv4 and IPv6 default route queries under a shared result structure and per-family functions. Improves clarity and extensibility by centralizing route logic, streamlining detection of preferred interfaces, and updating all consumers to use the new API. Prepares for more robust multi-protocol network information handling.
1 parent d9455ad commit a84c4dc

16 files changed

Lines changed: 579 additions & 205 deletions

src/common/netif/netif.c

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,23 @@
22

33
#ifndef _WIN32
44
#include <net/if.h>
5-
#else
6-
#include <ws2tcpip.h>
7-
#include <iphlpapi.h>
5+
#include <netinet/in.h>
86
#endif
97

10-
bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex, uint32_t* preferredSourceAddr);
11-
enum { IF_INDEX_UNINITIALIZED = (uint32_t) -1, IF_INDEX_INVALID = (uint32_t) -2 };
12-
static uint32_t ifIndex = IF_INDEX_UNINITIALIZED;
13-
static char ifName[IF_NAMESIZE + 1];
14-
static uint32_t preferredSourceAddr = 0;
15-
16-
static inline void init()
8+
const FFNetifDefaultRouteResult* ffNetifGetDefaultRouteV4(void)
179
{
18-
if (ifIndex == (uint32_t) IF_INDEX_UNINITIALIZED) {
19-
if (!ffNetifGetDefaultRouteImpl(ifName, &ifIndex, &preferredSourceAddr))
20-
ifIndex = (uint32_t) IF_INDEX_INVALID;
10+
static FFNetifDefaultRouteResult result;
11+
if (result.status == FF_NETIF_UNINITIALIZED) {
12+
result.status = ffNetifGetDefaultRouteImplV4(&result) ? FF_NETIF_OK : FF_NETIF_INVALID;
2113
}
14+
return &result;
2215
}
2316

24-
const char* ffNetifGetDefaultRouteIfName()
25-
{
26-
init();
27-
return ifName;
28-
}
29-
30-
uint32_t ffNetifGetDefaultRouteIfIndex()
17+
const FFNetifDefaultRouteResult* ffNetifGetDefaultRouteV6(void)
3118
{
32-
init();
33-
return ifIndex;
34-
}
35-
36-
uint32_t ffNetifGetDefaultRoutePreferredSourceAddr()
37-
{
38-
init();
39-
return preferredSourceAddr;
19+
static FFNetifDefaultRouteResult result;
20+
if (result.status == FF_NETIF_UNINITIALIZED) {
21+
result.status = ffNetifGetDefaultRouteImplV6(&result) ? FF_NETIF_OK : FF_NETIF_INVALID;
22+
}
23+
return &result;
4024
}

src/common/netif/netif.h

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,29 @@
22

33
#include "fastfetch.h"
44

5-
const char* ffNetifGetDefaultRouteIfName();
6-
uint32_t ffNetifGetDefaultRouteIfIndex();
7-
uint32_t ffNetifGetDefaultRoutePreferredSourceAddr();
5+
#ifndef _WIN32
6+
#include <net/if.h>
7+
#include <netinet/in.h>
8+
#endif
9+
10+
typedef enum __attribute__((__packed__)) FFNetifDefaultRouteResultStatus {
11+
FF_NETIF_UNINITIALIZED,
12+
FF_NETIF_INVALID,
13+
FF_NETIF_OK
14+
} FFNetifDefaultRouteResultStatus;
15+
16+
typedef struct FFNetifDefaultRouteResult {
17+
uint32_t ifIndex;
18+
19+
#ifndef _WIN32
20+
char ifName[IF_NAMESIZE + 1];
21+
uint32_t preferredSourceAddrV4;
22+
#endif
23+
enum FFNetifDefaultRouteResultStatus status;
24+
} FFNetifDefaultRouteResult;
25+
26+
bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result);
27+
bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result);
28+
29+
const FFNetifDefaultRouteResult* ffNetifGetDefaultRouteV4(void);
30+
const FFNetifDefaultRouteResult* ffNetifGetDefaultRouteV6(void);

src/common/netif/netif_bsd.c

Lines changed: 72 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,8 @@ get_rt_address(struct rt_msghdr *rtm, int desired)
4242
return NULL;
4343
}
4444

45-
bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex, uint32_t* preferredSourceAddr)
45+
bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
4646
{
47-
if (preferredSourceAddr)
48-
*preferredSourceAddr = 0;
49-
5047
//https://github.com/hashPirate/copenheimer-masscan-fork/blob/36f1ed9f7b751a7dccd5ed27874e2e703db7d481/src/rawsock-getif.c#L104
5148

5249
FF_AUTO_CLOSE_FD int pfRoute = socket(PF_ROUTE, SOCK_RAW, AF_INET);
@@ -98,14 +95,80 @@ bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex,
9895
)
9996
{
10097
assert(sdl->sdl_nlen <= IF_NAMESIZE);
101-
memcpy(iface, sdl->sdl_data, sdl->sdl_nlen);
102-
iface[sdl->sdl_nlen] = '\0';
103-
*ifIndex = sdl->sdl_index;
98+
memcpy(result->ifName, sdl->sdl_data, sdl->sdl_nlen);
99+
result->ifName[sdl->sdl_nlen] = '\0';
100+
result->ifIndex = sdl->sdl_index;
104101

105102
// Get the preferred source address
106103
struct sockaddr_in* src = (struct sockaddr_in*)get_rt_address(&rtmsg.hdr, RTA_IFA);
107-
if (preferredSourceAddr && src && src->sin_family == AF_INET)
108-
*preferredSourceAddr = src->sin_addr.s_addr;
104+
if (src && src->sin_family == AF_INET)
105+
result->preferredSourceAddrV4 = src->sin_addr.s_addr;
106+
107+
return true;
108+
}
109+
return false;
110+
}
111+
}
112+
113+
return false;
114+
}
115+
116+
bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result)
117+
{
118+
//https://github.com/hashPirate/copenheimer-masscan-fork/blob/36f1ed9f7b751a7dccd5ed27874e2e703db7d481/src/rawsock-getif.c#L104
119+
120+
FF_AUTO_CLOSE_FD int pfRoute = socket(PF_ROUTE, SOCK_RAW, AF_INET6);
121+
if (pfRoute < 0)
122+
return false;
123+
124+
{
125+
struct timeval timeout = {1, 0};
126+
setsockopt(pfRoute, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
127+
setsockopt(pfRoute, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout));
128+
}
129+
130+
int pid = getpid();
131+
132+
struct {
133+
struct rt_msghdr hdr;
134+
struct sockaddr_in6 dst;
135+
uint8_t data[512];
136+
} rtmsg = {
137+
.hdr = {
138+
.rtm_type = RTM_GET,
139+
.rtm_flags = RTF_UP | RTF_GATEWAY,
140+
.rtm_version = RTM_VERSION,
141+
.rtm_addrs = RTA_DST | RTA_IFP | RTA_IFA,
142+
.rtm_msglen = sizeof(rtmsg.hdr) + sizeof(rtmsg.dst),
143+
.rtm_pid = pid,
144+
.rtm_seq = 1,
145+
},
146+
.dst = {
147+
.sin6_family = AF_INET6,
148+
#ifndef __sun
149+
.sin6_len = sizeof(rtmsg.dst),
150+
#endif
151+
},
152+
};
153+
154+
if (write(pfRoute, &rtmsg, rtmsg.hdr.rtm_msglen) != rtmsg.hdr.rtm_msglen)
155+
return false;
156+
157+
while (read(pfRoute, &rtmsg, sizeof(rtmsg)) > 0)
158+
{
159+
if (rtmsg.hdr.rtm_seq == 1 && rtmsg.hdr.rtm_pid == pid)
160+
{
161+
struct sockaddr_dl* sdl = (struct sockaddr_dl *)get_rt_address(&rtmsg.hdr, RTA_IFP);
162+
if (sdl
163+
#ifndef __sun
164+
&& sdl->sdl_len
165+
#endif
166+
)
167+
{
168+
assert(sdl->sdl_nlen <= IF_NAMESIZE);
169+
memcpy(result->ifName, sdl->sdl_data, sdl->sdl_nlen);
170+
result->ifName[sdl->sdl_nlen] = '\0';
171+
result->ifIndex = sdl->sdl_index;
109172

110173
return true;
111174
}

src/common/netif/netif_haiku.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,8 @@
1111

1212
// loosely based on Haiku's src/bin/network/route/route.cpp
1313

14-
bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex, uint32_t* preferredSourceAddr)
14+
bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
1515
{
16-
if (preferredSourceAddr)
17-
*preferredSourceAddr = 0;
18-
19-
// TODO: AF_INET6
2016
FF_AUTO_CLOSE_FD int pfRoute = socket(AF_INET, SOCK_RAW, AF_INET);
2117
if (pfRoute < 0)
2218
return false;
@@ -45,8 +41,9 @@ bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex,
4541

4642
while (interface < end) {
4743
if (interface->ifr_route.flags & RTF_DEFAULT) {
48-
strlcpy(iface, interface->ifr_name, IF_NAMESIZE);
49-
*ifIndex = if_nametoindex(interface->ifr_name);
44+
strlcpy(result->ifName, interface->ifr_name, IF_NAMESIZE);
45+
result->ifIndex = if_nametoindex(interface->ifr_name);
46+
// TODO: Get the preferred source address
5047
return true;
5148
}
5249

@@ -64,3 +61,9 @@ bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex,
6461

6562
return false;
6663
}
64+
65+
bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result)
66+
{
67+
// TODO: AF_INET6
68+
return false;
69+
}

0 commit comments

Comments
 (0)