commit 774975c0a33418ee74e7f215aa82c671334f514e
parent 8829486d5587ca59a8609dcd865acb5e84a8dbcf
Author: Lucas <lucas@sexy.is>
Date:   Tue, 16 Jul 2019 11:25:11 +0000
netspeed: use getifaddrs on OpenBSD...
instead of hand-rolled, low-level route messages.
Diffstat:
| M | netspeed.c |  |  | 47 | ++++++++++++++++++----------------------------- | 
1 file changed, 18 insertions(+), 29 deletions(-)
diff --git a/netspeed.c b/netspeed.c
@@ -41,48 +41,37 @@ updatenetspeed(char *buf, size_t len, uint64_t rxbytes, uint64_t txbytes)
 
 #ifdef __OpenBSD__
 #include <sys/socket.h>
-#include <net/if.h>
-#include <net/if_dl.h>
-#include <net/route.h>
-#include <sys/sysctl.h>
+#include <sys/types.h>
+#include <net/if.h> /* struct if_data */
+#include <ifaddrs.h>
 
 int
 netspeedread(void *arg, char *buf, size_t len)
 {
-	int mib[6] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 };
-	char *ifname = arg;
-	struct rt_msghdr *rtm;
-	struct if_msghdr *ifm;
-	struct sockaddr_dl *sdl;
-	void *lim, *next, *rtmraw;
+	char *ifa_name = arg;
+	struct if_data *ifa_data;
+	struct ifaddrs *ifa, *ifap;
 	uint64_t rxbytes, txbytes;
-	size_t sz;
 
-	if (sysctl(mib, 6, NULL, &sz, NULL, 0) < 0)
-		return -1;
-	if (!(rtmraw = malloc(sz)))
-		return -1;
-	if (sysctl(mib, 6, rtmraw, &sz, NULL, 0) < 0) {
-		free(rtmraw);
+	if (getifaddrs(&ifap) == -1) {
+		warn("getifaddrs");
 		return -1;
 	}
-	lim = rtmraw + sz;
+
 	rxbytes = txbytes = 0;
-	for (next = rtmraw; next < lim; next += rtm->rtm_msglen) {
-		rtm = (struct rt_msghdr *)next;
-		if (rtm->rtm_version != RTM_VERSION || rtm->rtm_type
-		    != RTM_IFINFO)
+
+	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+		if (strcmp(ifa_name, ifa->ifa_name) != 0)
 			continue;
-		ifm = (struct if_msghdr *)next;
-		sdl = (struct sockaddr_dl *)(next + ifm->ifm_hdrlen);
-		if (sdl->sdl_family != AF_LINK
-		    || strncmp(ifname, sdl->sdl_data, sdl->sdl_nlen) != 0)
+		if (ifa->ifa_data == NULL)
 			continue;
-		rxbytes = ifm->ifm_data.ifi_ibytes;
-		txbytes = ifm->ifm_data.ifi_obytes;
+		ifa_data = ifa->ifa_data;
+		rxbytes += ifa_data->ifi_ibytes;
+		txbytes += ifa_data->ifi_obytes;
 	}
+
 	updatenetspeed(buf, len, rxbytes, txbytes);
-	free(rtmraw);
+	freeifaddrs(ifap);
 
 	return 0;
 }