--- epplets/net.c.orig	Tue Jul 31 23:50:29 2001
+++ epplets/net.c	Fri Aug 10 14:54:32 2001
@@ -35,6 +35,22 @@
 # include <kstat.h>
 # include <sys/sysinfo.h>
 #endif
+
+#ifdef __FreeBSD__
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <net/if_var.h>
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+
+#include <kvm.h>
+#include <nlist.h>
+
+#endif
+
 #include "epplet.h"
 #include "net.h"
 
@@ -51,6 +67,18 @@
   char buff[256], **names = NULL, *s;
   unsigned long i;
 
+#ifdef __FreeBSD__
+
+	kvm_t *kd;
+	struct nlist magicsymbol[] = { {"_ifnet"}, {""} };
+	char name[32], type[16];
+	int num;
+	unsigned long ifnetaddr;
+	struct ifnet ifnet;
+	struct ifnethead ifnethead;	
+
+#endif
+
   names = (char **) malloc(sizeof(char *));
   memset(names, 0, sizeof(char *));
 
@@ -80,6 +108,66 @@
   return (names);
 #elif defined(__sun__)
   return ((char **) NULL);
+#elif defined(__FreeBSD__)
+
+	if((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL)) == NULL)
+	{
+		perror("kvm_open()");
+		return NULL;
+	}
+	
+	if(kvm_nlist(kd, magicsymbol) == -1)
+	{
+		perror("kvm_nlist()");
+		kvm_close(kd);
+		return NULL;
+	}
+	
+	if(kvm_read(kd, magicsymbol[0].n_value, &ifnethead, sizeof(ifnethead)) == -1)
+	{
+		perror("kread magic");
+		kvm_close(kd);
+		return NULL;
+	}
+	
+	ifnetaddr = (unsigned long)TAILQ_FIRST(&ifnethead);
+	
+	if(kvm_read(kd, ifnetaddr, &ifnet, sizeof(ifnet)) == -1)
+	{
+		perror("kvm_read ifnet\n");
+		kvm_close(kd);
+		return NULL;
+	}
+	
+	num = 0;
+	while(ifnetaddr)
+	{
+		if(kvm_read(kd, ifnetaddr, &ifnet, sizeof(ifnet)) == -1 ||  
+			kvm_read(kd, (long)ifnet.if_name, type, 16) == -1)
+		{
+			break;
+		}
+
+		type[15] = '\0';
+		ifnetaddr = (unsigned long)TAILQ_NEXT(&ifnet, if_link);
+		
+		snprintf(name, 32, "%s%d", type, ifnet.if_unit);
+
+		if((names = (char **)realloc(names, (++num + 1)*sizeof(char *))) == NULL)
+			return NULL;
+
+		asprintf(&names[num-1], "%s", name);
+		
+		names[num] = NULL;
+	}
+
+	kvm_close(kd);
+
+	if(count)
+		*count = num;
+
+	return names;
+	
 #else
   return ((char **) NULL);
 #endif
@@ -97,6 +185,21 @@
   unsigned char match = 0;
   FILE *fp;
   char buff[256], *colon = NULL, dev[64], in_str[64], out_str[64];
+#elif defined(__FreeBSD__)
+
+	kvm_t *kd;
+	struct nlist magicsymbol[] = { {"_ifnet"}, {""} };
+	char name[32], tname[16];
+	int match, net_layer;
+	struct sockaddr *sa;
+	unsigned long ifaddraddr, ifnetaddr, ifnetfound;
+	struct ifnet ifnet;
+	struct ifnethead ifnethead;
+	union {
+		struct ifaddr ifa;
+		struct in_ifaddr in;
+	} ifaddr;
+	
 #endif
 
   if (device == NULL) {
@@ -151,6 +254,104 @@
   }
   fclose(fp);
   return ((match) ? (0) : (ENODEV));
+#elif defined(__FreeBSD__)
+	
+	if((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL)) == NULL)
+	{
+		perror("kvm_open()");
+		return ENOENT;
+	}
+	
+	if(kvm_nlist(kd, magicsymbol) == -1)
+	{
+		perror("kvm_nlist()");
+		kvm_close(kd);
+		return ENOENT;
+	}
+	
+	if(kvm_read(kd, magicsymbol[0].n_value, &ifnethead, sizeof(ifnethead)) == -1)
+	{
+		perror("kread magic");
+		kvm_close(kd);
+		return ENOENT;
+	}
+	
+	ifnetaddr = (unsigned long)TAILQ_FIRST(&ifnethead);
+	
+	if(kvm_read(kd, ifnetaddr, &ifnet, sizeof(ifnet)) == -1)
+	{
+		perror("kvm_read ifnet\n");
+		kvm_close(kd);
+		return ENOENT;
+	}
+	
+	ifaddraddr = 0;
+	while(ifnetaddr || ifaddraddr)
+	{
+		if(ifaddraddr == 0)
+		{
+			ifnetfound = ifnetaddr;
+			if(kvm_read(kd, ifnetaddr, &ifnet, sizeof(ifnet)) == -1 ||  
+				kvm_read(kd, (long)ifnet.if_name, tname, 16) == -1)
+			{
+				perror("kread ifnet.if_name\n");
+				kvm_close(kd);
+				return ENOENT;
+			}
+	
+			tname[15] = '\0';
+			ifnetaddr = (unsigned long)TAILQ_NEXT(&ifnet, if_link);
+			snprintf(name, 32, "%s%d", tname, ifnet.if_unit);
+
+			if(strncasecmp(name, device, 16) != 0)
+				continue;
+
+			ifaddraddr = (unsigned long)TAILQ_FIRST(&ifnet.if_addrhead);
+		}
+		
+		*in_bytes = (double)ifnet.if_ibytes;
+		*out_bytes = (double)ifnet.if_obytes;
+		
+		if(kvm_read(kd, ifaddraddr, &ifaddr, sizeof(ifaddr)) == -1)
+		{
+			printf("kread ifaddr\n");
+			ifaddraddr=0;
+			continue;
+		}
+
+		match = 1;
+		
+		sa = (struct sockaddr *)((char *)ifaddr.ifa.ifa_addr - 
+			(char *)ifaddraddr + (char *)&ifaddr);
+
+		switch(sa->sa_family)
+		{
+			case AF_INET:
+				net_layer = 1;
+				break;
+#ifdef AF_INET6
+			case AF_INET6:
+				net_layer = 1;
+				break;
+#endif
+			default:
+				net_layer = 0;
+		}
+
+		if(net_layer)
+		{
+			*in_bytes = (double)ifaddr.in.ia_ifa.if_ibytes;
+			*out_bytes = (double)ifaddr.in.ia_ifa.if_obytes;
+		}
+		
+		break;
+	}
+	
+	kvm_close(kd);
+	
+	/* XXX: errno=ENODEV; return -1; ??? */
+	return (match ? 0 : ENODEV);
+	
 #else
   /* Unsupported platform. */
   if (in_bytes != NULL) {
