Skip to content

Commit 8cfee9d

Browse files
committed
Netif: unifies BSD netif handling
1 parent 64568b3 commit 8cfee9d

4 files changed

Lines changed: 240 additions & 219 deletions

File tree

CMakeLists.txt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,7 @@ elseif(FreeBSD)
638638
list(APPEND LIBFASTFETCH_SRC
639639
src/common/dbus.c
640640
src/common/io/io_unix.c
641+
src/common/netif/netif_bsd.c
641642
src/common/networking/networking_linux.c
642643
src/common/processing_linux.c
643644
src/common/sysctl.c
@@ -717,13 +718,11 @@ elseif(FreeBSD)
717718
)
718719
if(DragonFly)
719720
list(APPEND LIBFASTFETCH_SRC
720-
src/common/netif/netif_obsd.c
721721
src/detection/bluetooth/bluetooth_nosupport.c
722722
src/detection/wifi/wifi_nosupport.c
723723
)
724724
else()
725725
list(APPEND LIBFASTFETCH_SRC
726-
src/common/netif/netif_bsd.c
727726
src/detection/bluetooth/bluetooth_bsd.c
728727
src/detection/wifi/wifi_bsd.c
729728
)
@@ -814,7 +813,7 @@ elseif(OpenBSD)
814813
list(APPEND LIBFASTFETCH_SRC
815814
src/common/dbus.c
816815
src/common/io/io_unix.c
817-
src/common/netif/netif_obsd.c
816+
src/common/netif/netif_bsd.c
818817
src/common/networking/networking_linux.c
819818
src/common/processing_linux.c
820819
src/common/sysctl.c
@@ -896,7 +895,7 @@ elseif(OpenBSD)
896895
elseif(APPLE)
897896
list(APPEND LIBFASTFETCH_SRC
898897
src/common/io/io_unix.c
899-
src/common/netif/netif_bsd.c
898+
src/common/netif/netif_apple.c
900899
src/common/networking/networking_linux.c
901900
src/common/processing_linux.c
902901
src/common/sysctl.c
@@ -1042,7 +1041,7 @@ elseif(SunOS)
10421041
list(APPEND LIBFASTFETCH_SRC
10431042
src/common/dbus.c
10441043
src/common/io/io_unix.c
1045-
src/common/netif/netif_bsd.c
1044+
src/common/netif/netif_apple.c
10461045
src/common/networking/networking_linux.c
10471046
src/common/processing_linux.c
10481047
src/detection/battery/battery_nosupport.c

src/common/netif/netif_apple.c

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
#include "netif.h"
2+
3+
#include "common/io/io.h"
4+
#include "util/mallocHelper.h"
5+
6+
#include <net/if.h>
7+
#include <net/if_dl.h>
8+
#include <net/route.h>
9+
#include <netinet/in.h>
10+
#include <sys/socket.h>
11+
12+
#define ROUNDUP2(a, n) ((a) > 0 ? (1 + (((a) - 1U) | ((n) - 1))) : (n))
13+
14+
#if __APPLE__
15+
// https://github.com/apple-oss-distributions/network_cmds/blob/8f38231438e6a4d16ef8015e97e12c2c05105644/rtsol.tproj/if.c#L243
16+
#define ROUNDUP(a) ROUNDUP2((a), sizeof(uint32_t))
17+
#elif __sun
18+
// https://github.com/illumos/illumos-gate/blob/95b8c88950fa7b19af46bc63230137cf96b0bff7/usr/src/cmd/cmd-inet/usr.sbin/route.c#L339
19+
#define ROUNDUP(a) ROUNDUP2((a), sizeof(long))
20+
#else
21+
#error unknown platform
22+
#endif
23+
24+
static struct sockaddr *
25+
get_rt_address(struct rt_msghdr *rtm, int desired)
26+
{
27+
struct sockaddr *sa = (struct sockaddr *)(rtm + 1);
28+
29+
for (int i = 0; i < RTAX_MAX; i++)
30+
{
31+
if (rtm->rtm_addrs & (1 << i))
32+
{
33+
if ((1 << i) == desired)
34+
return sa;
35+
36+
#ifndef __sun
37+
uint32_t salen = sa->sa_len;
38+
#else
39+
uint32_t salen;
40+
// https://github.com/illumos/illumos-gate/blob/95b8c88950fa7b19af46bc63230137cf96b0bff7/usr/src/cmd/cmd-inet/usr.sbin/route.c#L2941
41+
switch (sa->sa_family) {
42+
case AF_INET:
43+
salen = sizeof (struct sockaddr_in);
44+
case AF_LINK:
45+
salen = sizeof (struct sockaddr_dl);
46+
case AF_INET6:
47+
salen = sizeof (struct sockaddr_in6);
48+
default:
49+
salen = sizeof (struct sockaddr);
50+
}
51+
#endif
52+
sa = (struct sockaddr *)(ROUNDUP(salen) + (char *)sa);
53+
}
54+
}
55+
return NULL;
56+
}
57+
58+
bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
59+
{
60+
//https://github.com/hashPirate/copenheimer-masscan-fork/blob/36f1ed9f7b751a7dccd5ed27874e2e703db7d481/src/rawsock-getif.c#L104
61+
62+
FF_AUTO_CLOSE_FD int pfRoute = socket(PF_ROUTE, SOCK_RAW, AF_INET);
63+
if (pfRoute < 0)
64+
return false;
65+
66+
{
67+
struct timeval timeout = {1, 0};
68+
setsockopt(pfRoute, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
69+
setsockopt(pfRoute, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout));
70+
}
71+
72+
int pid = getpid();
73+
74+
struct {
75+
struct rt_msghdr hdr;
76+
struct sockaddr_in dst;
77+
uint8_t data[512];
78+
} rtmsg = {
79+
.hdr = {
80+
.rtm_type = RTM_GET,
81+
.rtm_flags = RTF_UP | RTF_GATEWAY,
82+
.rtm_version = RTM_VERSION,
83+
.rtm_addrs = RTA_DST | RTA_IFP | RTA_IFA,
84+
.rtm_msglen = sizeof(rtmsg.hdr) + sizeof(rtmsg.dst),
85+
.rtm_pid = pid,
86+
.rtm_seq = 1,
87+
},
88+
.dst = {
89+
.sin_family = AF_INET,
90+
#ifndef __sun
91+
.sin_len = sizeof(rtmsg.dst),
92+
#endif
93+
},
94+
};
95+
96+
if (send(pfRoute, &rtmsg, rtmsg.hdr.rtm_msglen, 0) != rtmsg.hdr.rtm_msglen)
97+
return false;
98+
99+
while (recv(pfRoute, &rtmsg, sizeof(rtmsg), 0) > 0 && !(rtmsg.hdr.rtm_seq == 1 && rtmsg.hdr.rtm_pid == pid))
100+
;
101+
102+
if ((rtmsg.hdr.rtm_flags & (RTF_UP | RTF_GATEWAY)) == (RTF_UP | RTF_GATEWAY))
103+
{
104+
struct sockaddr_dl* sdl = (struct sockaddr_dl *)get_rt_address(&rtmsg.hdr, RTA_IFP);
105+
if (sdl
106+
#ifndef __sun
107+
&& sdl->sdl_len
108+
#endif
109+
)
110+
{
111+
assert(sdl->sdl_nlen <= IF_NAMESIZE);
112+
memcpy(result->ifName, sdl->sdl_data, sdl->sdl_nlen);
113+
result->ifName[sdl->sdl_nlen] = '\0';
114+
result->ifIndex = sdl->sdl_index;
115+
116+
// Get the preferred source address
117+
struct sockaddr_in* src = (struct sockaddr_in*)get_rt_address(&rtmsg.hdr, RTA_IFA);
118+
if (src && src->sin_family == AF_INET)
119+
result->preferredSourceAddrV4 = src->sin_addr.s_addr;
120+
121+
return true;
122+
}
123+
return false;
124+
}
125+
126+
return false;
127+
}
128+
129+
bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result)
130+
{
131+
//https://github.com/hashPirate/copenheimer-masscan-fork/blob/36f1ed9f7b751a7dccd5ed27874e2e703db7d481/src/rawsock-getif.c#L104
132+
133+
FF_AUTO_CLOSE_FD int pfRoute = socket(PF_ROUTE, SOCK_RAW, AF_INET6);
134+
if (pfRoute < 0)
135+
return false;
136+
137+
{
138+
struct timeval timeout = {1, 0};
139+
setsockopt(pfRoute, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
140+
setsockopt(pfRoute, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout));
141+
}
142+
143+
int pid = getpid();
144+
145+
struct {
146+
struct rt_msghdr hdr;
147+
struct sockaddr_in6 dst;
148+
uint8_t data[512];
149+
} rtmsg = {
150+
.hdr = {
151+
.rtm_type = RTM_GET,
152+
.rtm_flags = RTF_UP | RTF_GATEWAY,
153+
.rtm_version = RTM_VERSION,
154+
.rtm_addrs = RTA_DST | RTA_IFP,
155+
.rtm_msglen = sizeof(rtmsg.hdr) + sizeof(rtmsg.dst),
156+
.rtm_pid = pid,
157+
.rtm_seq = 2,
158+
},
159+
.dst = {
160+
.sin6_family = AF_INET6,
161+
#ifndef __sun
162+
.sin6_len = sizeof(rtmsg.dst),
163+
#endif
164+
},
165+
};
166+
167+
if (send(pfRoute, &rtmsg, rtmsg.hdr.rtm_msglen, 0) != rtmsg.hdr.rtm_msglen)
168+
return false;
169+
170+
while (recv(pfRoute, &rtmsg, sizeof(rtmsg), 0) > 0 && !(rtmsg.hdr.rtm_seq == 2 && rtmsg.hdr.rtm_pid == pid))
171+
;
172+
173+
if ((rtmsg.hdr.rtm_flags & (RTF_UP | RTF_GATEWAY)) == (RTF_UP | RTF_GATEWAY))
174+
{
175+
struct sockaddr_dl* sdl = (struct sockaddr_dl *)get_rt_address(&rtmsg.hdr, RTA_IFP);
176+
if (sdl
177+
#ifndef __sun
178+
&& sdl->sdl_len
179+
#endif
180+
)
181+
{
182+
assert(sdl->sdl_nlen <= IF_NAMESIZE);
183+
memcpy(result->ifName, sdl->sdl_data, sdl->sdl_nlen);
184+
result->ifName[sdl->sdl_nlen] = '\0';
185+
result->ifIndex = sdl->sdl_index;
186+
187+
return true;
188+
}
189+
return false;
190+
}
191+
192+
return false;
193+
}

0 commit comments

Comments
 (0)