diff -u -r old/wmnet-1.06/Imakefile new/wmnet-1.06/Imakefile --- old/wmnet-1.06/Imakefile Thu May 4 17:34:29 2000 +++ new/wmnet-1.06/Imakefile Fri Aug 25 14:00:14 2000 @@ -15,9 +15,14 @@ INSTPGMFLAGS = -s -g kmem -m 2755 #endif +#if defined (SunArchitecture) +LOCAL_LIBRARIES = $(XLIB) -lm -lkstat +CCOPTIONS = +#endif + LINTLIBS = $(LINTXLIB) -#if defined (FreeBSDArchitecture) || defined (OpenBSDArchitecture) +#if defined (FreeBSDArchitecture) || defined (OpenBSDArchitecture) || defined (SunArchitecture) SRCS = wmnet.c drivers.c getopt.c getopt1.c OBJS = wmnet.o drivers.o getopt.o getopt1.o #else diff -u -r old/wmnet-1.06/config.h new/wmnet-1.06/config.h --- old/wmnet-1.06/config.h Thu May 4 17:34:29 2000 +++ new/wmnet-1.06/config.h Fri Aug 25 14:05:20 2000 @@ -12,7 +12,16 @@ #endif +#if defined (sun) +/* + * This driver uses the Solaris kstat(3) mechanism to acquire interface + * statistics. It's a lot more elegant than grovelling through kernel + * memory. + */ +#define USE_KSTAT + +#endif #ifdef linux diff -u -r old/wmnet-1.06/drivers.c new/wmnet-1.06/drivers.c --- old/wmnet-1.06/drivers.c Thu May 4 17:34:29 2000 +++ new/wmnet-1.06/drivers.c Fri Aug 25 14:04:13 2000 @@ -37,6 +37,11 @@ int kvm_updateStats(void); #endif /* USE_KVM */ +#ifdef USE_KSTAT +#include +int kstat_test(void); +int kstat_updateStats(void); +#endif /* USE_KSTAT */ #ifdef USE_LINUX_PPP #include @@ -104,6 +109,9 @@ #ifdef USE_KVM {"kmem",kvm_updateStats, kvm_test}, #endif +#ifdef USE_KSTAT + {"kstat", kstat_updateStats, kstat_test}, +#endif {NULL, NULL} }; @@ -502,8 +510,118 @@ } -#endif - +#endif /* KVM */ - - + +#ifdef USE_KSTAT + +kstat_ctl_t *kc = NULL; +kstat_t *if_ksp = NULL; + +int kstat_test(void) +{ + kstat_t *ksp; + + if (kc == NULL) { + if ((kc = kstat_open()) == NULL) { + perror("wmnet [kstat]: can't open /dev/kstat\n"); + return (False); + } + } + + /* + * If no device given, take the first thing we find of class 'net' + * which exports the four kstats we need. + */ + if (device == NULL) { + for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) { + if (strcmp(ksp->ks_class, "net") == 0) { + kstat_read(kc, ksp, NULL); + if (kstat_data_lookup(ksp, "ipackets") && + kstat_data_lookup(ksp, "opackets") && + kstat_data_lookup(ksp, "rbytes") && + kstat_data_lookup(ksp, "obytes")) { + if_ksp = ksp; + break; + } + } + } + if (if_ksp == NULL) { + fprintf(stderr, "wmnet [kstat]: no network interface " + "exporting kstats found\n"); + return (False); + } else { + fprintf(stderr, "wmnet [kstat]: monitoring %s\n", + ksp->ks_name); + } + } else { + if ((if_ksp = (kstat_lookup(kc, NULL, -1, device))) == NULL) { + fprintf(stderr, "wmnet [kstat]: no network interface " + "%s exporting kstats found\n", device); + return (False); + } + } + + return (True); +} + +int kstat_updateStats(void) +{ + kstat_named_t *in_pkt, *in_byte, *out_pkt, *out_byte; + tx = rx = False; + + if (kstat_read(kc, if_ksp, NULL) == -1) { + (void) fprintf(stderr, "wmnet [kstat]: kstat_read failed\n"); + exit (1); + } + + if ((in_pkt = (kstat_named_t *) kstat_data_lookup(if_ksp, "ipackets")) + == NULL) { + (void) fprintf(stderr, "wmnet [kstat]: kstat_data_lookup " + "(ipackets) failed\n"); + exit (1); + } + + totalpackets_in = (in_pkt->value.ui32); + if (totalpackets_in != lastpackets_in) { + if ((in_byte = (kstat_named_t *) kstat_data_lookup(if_ksp, + "rbytes")) == NULL) { + (void) fprintf(stderr, "wmnet [kstat]: " + "kstat_data_lookup (rbytes) failed\n"); + exit (1); + } + totalbytes_in = in_byte->value.ui32; + diffpackets_in += totalpackets_in - lastpackets_in; + diffbytes_in += totalbytes_in - lastbytes_in; + lastpackets_in = totalpackets_in; + lastbytes_in = totalbytes_in; + rx = True; + } + + if ((out_pkt = (kstat_named_t *) kstat_data_lookup(if_ksp, "opackets")) + == NULL) { + (void) fprintf(stderr, "wmnet [kstat]: kstat_data_lookup " + "(opackets) failed\n"); + exit (1); + } + + totalpackets_out = (out_pkt->value.ui32); + if (totalpackets_out != lastpackets_out) { + if ((out_byte = (kstat_named_t *) kstat_data_lookup(if_ksp, + "obytes")) == NULL) { + (void) fprintf(stderr, "wmnet [kstat]: " + "kstat_data_lookup (obytes) failed\n"); + exit (1); + } + totalbytes_out = out_byte->value.ui32; + diffpackets_out += totalpackets_out - lastpackets_out; + diffbytes_out += totalbytes_out - lastbytes_out; + lastpackets_out = totalpackets_out; + lastbytes_out = totalbytes_out; + tx = True; + } + + return ((rx == current_rx) && (tx == current_tx)); +} + +#endif /* Solaris Kstats */ diff -u -r old/wmnet-1.06/wmnet.c new/wmnet-1.06/wmnet.c --- old/wmnet-1.06/wmnet.c Thu May 4 18:01:14 2000 +++ new/wmnet-1.06/wmnet.c Fri Aug 25 14:07:46 2000 @@ -58,6 +58,10 @@ #if defined (__FreeBSD__) || defined (__OpenBSD__) # include # include"getopt.h" +#elif defined (sun) +# include +# include +# include "getopt.h" #else # include #endif