$OpenBSD: patch-src_net_c,v 1.1 2003/01/03 17:58:34 naddy Exp $
--- src/net.c.orig	Mon Jul  1 04:17:27 2002
+++ src/net.c	Wed Jan  1 22:07:45 2003
@@ -120,10 +120,10 @@ static gint	(*is_ISDN_online)();
 
 /* -------- FreeBSD / NetBSD / OpenBSD ------------------------------------ */
 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
-#include <sys/sysctl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
 #include <net/if.h>
-#include <net/if_dl.h>
-#include <net/route.h>
+#include <ifaddrs.h>
 
 #define	LOCK_DIRECTORY		"/var/spool/lock"
 
@@ -133,74 +133,39 @@ static TimerType	timer_defaults[] =
 	{"ppp0", TIMER_TYPE_PPP }
 	};
 
-static int	mib[] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 };
-static char	*buf;
-static int	alloc;
-
 void
 read_bsd_net_data()
 	{
 	GList			*list;
 	NetMon			*net;
-	struct if_msghdr	*ifm, *nextifm;
-	struct sockaddr_dl	*sdl;
-	char			*lim, *next;
-	size_t			needed;
-	gchar			s[32];
-
-	if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
-		return;
-	if (alloc < needed)
-		{
-		if (buf != NULL)
-			free(buf);
-		buf = malloc(needed);
-		if (buf == NULL)
-			return;
-		alloc = needed;
-		}
+	struct ifaddrs		*ifap, *ifa;
+	struct if_data		*ifd;
 
-	if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
+	if (getifaddrs(&ifap) < 0)
 		return;
-	lim = buf + needed;
 
-	next = buf;
-	while (next < lim)
+	for (ifa = ifap; ifa; ifa = ifa->ifa_next)
 		{
-		ifm = (struct if_msghdr *)next;
-		if (ifm->ifm_type != RTM_IFINFO)
-			return;
-		next += ifm->ifm_msglen;
-
-		while (next < lim)
+		if (ifa->ifa_flags & IFF_UP)
 			{
-			nextifm = (struct if_msghdr *)next;
-			if (nextifm->ifm_type != RTM_NEWADDR)
-				break;
-			next += nextifm->ifm_msglen;
-			}
-
-		if (ifm->ifm_flags & IFF_UP)
-			{
-			sdl = (struct sockaddr_dl *)(ifm + 1);
-			if (sdl->sdl_family != AF_LINK)
+			if (ifa->ifa_addr->sa_family != AF_LINK)
 				continue;
-			strncpy(s, sdl->sdl_data, sdl->sdl_nlen);
-			s[sdl->sdl_nlen] = '\0';
-
 			for (list = net_mon_list; list; list = list->next)
 				{
 				net = (NetMon *) list->data;
-				if (strcmp(net->name, s) == 0)
+				if (strcmp(net->name, ifa->ifa_name) == 0)
 					{
-					net->rx = ifm->ifm_data.ifi_ibytes;
-					net->tx = ifm->ifm_data.ifi_obytes;
+					ifd = (struct if_data *)ifa->ifa_data;
+					net->rx = ifd->ifi_ibytes;
+					net->tx = ifd->ifi_obytes;
 					net->rxtx_units = NET_UNITS_BYTES;
 					break;
 					}
 				}
 			}
 		}
+
+	freeifaddrs(ifap);
 	}
 
 static void
@@ -208,11 +173,7 @@ sync_bsd_net_interfaces()
 	{
 	GList			*list;
 	NetMon			*net;
-	struct if_msghdr	*ifm, *nextifm;
-	struct sockaddr_dl	*sdl;
-	char			*lim, *next;
-	size_t			needed;
-	gchar			s[32];
+	struct ifaddrs		*ifap, *ifa;
 
 	for (list = net_mon_list; list; list = list->next)
 		{
@@ -221,58 +182,19 @@ sync_bsd_net_interfaces()
 		net->state = NET_DOWN;
 		}
 
-	if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
+	if (getifaddrs(&ifap) < 0)
 		return;
-	if (alloc < needed)
-		{
-		if (buf != NULL)
-			free(buf);
-		buf = malloc(needed);
-		if (buf == NULL)
-			return;
-		alloc = needed;
-		}
-
-	if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
-		return;
-	lim = buf + needed;
 
-	next = buf;
-	while (next < lim)
+	for (ifa = ifap; ifa; ifa = ifa->ifa_next)
 		{
-		ifm = (struct if_msghdr *)next;
-		if (ifm->ifm_type != RTM_IFINFO)
-			return;
-
-		next += ifm->ifm_msglen;
-
-		while (next < lim)
+		if (ifa->ifa_flags & IFF_UP)
 			{
-			nextifm = (struct if_msghdr *)next;
-			if (nextifm->ifm_type != RTM_NEWADDR)
-				break;
-			next += nextifm->ifm_msglen;
-			}
-
-		if (ifm->ifm_flags & IFF_UP)
-			{
-			sdl = (struct sockaddr_dl *)(ifm + 1);
-			if (sdl->sdl_family != AF_LINK)
+			if (ifa->ifa_addr->sa_family != AF_LINK)
 				continue;
-			strncpy(s, sdl->sdl_data, sdl->sdl_nlen);
-			s[sdl->sdl_nlen] = '\0';
-#if 0
-			/* Should we skip lo0 and dummy0?  Actually,
-                        |  those who don't want to see it can disable
-                        |  it from config panel.
-			*/
-			if (!strncmp(s, "lo", 2) || !strncmp(s, "dummy", 5))
-				continue;
-#endif
 			for (list = net_mon_list; list; list = list->next)
 				{
 				net = (NetMon *) list->data;
-				if (strcmp(net->name, s) == 0)
+				if (strcmp(net->name, ifa->ifa_name) == 0)
 					{
 					net->state = NET_UP;
 					break;
@@ -281,13 +203,15 @@ sync_bsd_net_interfaces()
 			if (list == NULL)
 				{
 				net = g_new0(NetMon, 1);
-				net->name = g_strdup(s);
+				net->name = g_strdup(ifa->ifa_name);
 				net_mon_list = g_list_append(net_mon_list, net);
 				net->state = NET_UP;
 				net->old_state = NET_DOWN;
 				}
 			}
 		}
+
+	freeifaddrs(ifap);
 	}
 #endif
 
