auxstats: get network stats in a portable manner on FreeBSD

as the old grody way doesn't work any more on FreeBSD-10 and later.
This commit is contained in:
Bakul Shah 2018-01-19 20:03:37 -08:00 committed by David du Colombier
parent 019be4481f
commit da8a485fc1

View file

@ -18,10 +18,9 @@
#include <limits.h>
#include <libc.h>
#include <bio.h>
#include <ifaddrs.h>
#include "dat.h"
/* XXX: #if __FreeBSD_version */
void xapm(int);
void xloadavg(int);
void xcpu(int);
@ -45,7 +44,6 @@ void (*statfn[])(int) =
static kvm_t *kvm;
static struct nlist nl[] = {
{ "_ifnet" },
{ "_cp_time" },
{ "" }
};
@ -86,45 +84,28 @@ kread(ulong addr, char *buf, int size)
void
xnet(int first)
{
struct ifaddrs *ifap, *ifa;
ulong out, in, outb, inb, err;
static ulong ifnetaddr;
ulong addr;
struct ifnet ifnet;
struct ifnethead ifnethead;
char name[16];
if(first)
return;
if(ifnetaddr == 0){
ifnetaddr = nl[0].n_value;
if(ifnetaddr == 0)
return;
}
if(kread(ifnetaddr, (char*)&ifnethead, sizeof ifnethead) < 0)
if (getifaddrs(&ifap) != 0)
return;
out = in = outb = inb = err = 0;
addr = (ulong)TAILQ_FIRST(&ifnethead);
while(addr){
#if __FreeBSD_version < 500000
if(kread(addr, (char*)&ifnet, sizeof ifnet) < 0
|| kread((ulong)ifnet.if_name, name, 16) < 0)
return;
#else
if(kread(addr, (char*)&ifnet, sizeof ifnet) < 0
|| kread((ulong)ifnet.if_dname, name, 16) < 0)
return;
#endif
name[15] = 0;
addr = (ulong)TAILQ_NEXT(&ifnet, if_link);
out += ifnet.if_opackets;
in += ifnet.if_ipackets;
outb += ifnet.if_obytes;
inb += ifnet.if_ibytes;
err += ifnet.if_oerrors+ifnet.if_ierrors;
#define IFA_STAT(s) (((struct if_data *)ifa->ifa_data)->ifi_ ## s)
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
if (ifa->ifa_addr->sa_family != AF_LINK)
continue;
out += IFA_STAT(opackets);
in += IFA_STAT(ipackets);
outb += IFA_STAT(obytes);
inb += IFA_STAT(ibytes);
err += IFA_STAT(oerrors) + IFA_STAT(ierrors);
}
freeifaddrs(ifap);
Bprint(&bout, "etherin %lud 1000\n", in);
Bprint(&bout, "etherout %lud 1000\n", out);
Bprint(&bout, "etherinb %lud 1000000\n", inb);