Subject: Re: CVS commit: src/sbin/ifconfig
To: Manuel Bouyer <bouyer@antioche.eu.org>
From: Greg A. Woods <woods@weird.com>
List: tech-misc
Date: 04/13/2003 15:59:34
[ On Sunday, April 13, 2003 at 20:17:53 (+0200), Manuel Bouyer wrote: ]
> Subject: Re: CVS commit: src/sbin/ifconfig
>
> it's not as convenient as zeroing the counters. You can come 2 hours, or a
> day after zeroing them and see how they moved.

Well if you're going to wait that long, and if you're going to sample by
eye at random times, then you really want to have some way to remember
when exactly it was you started counting, no?

Wouldn't it be just as easy to write a little script which could record
the starting values and then show you the column deltas on demand?  This
could even be done relatively generically for input consisting of
columns numbers with the initial value for each column on the first line:

$ cat <<"__EOF__" > cdelta.awk
	NR == 1 {
		for (i = 1; i <= NF; i++) {
			S[i] = $i;
		}
	}
	NR > 1 {
		for (i = 1; i <= NF; i++) {
			printf("%d ", $i - S[i]);
		}
		print "";
	}
__EOF__

So then you just capture the initial values at your start time:

	$ netstat -i -I tlp0 -w 1 | sed -ne '3p;4q' > start.out

and with '-c count' support it is even easier:

	$ netstat -i -I tlp0 -w 1 -c 1 | tail -1 > start.out

A slightly smarter AWK script could deal with arbitrary headers, and a
smarter one yet could reproduce them in its output too, even using them
as column width hints.

Then use the start.out sample and a new sample to feed your AWK script
whenever you want a delta of the current values from that start time:

	$ (cat start.out; netstat -i -I tlp0 -w 1 | sed -ne '3p;4q') | awk -f cdelta.awk
	3572 0 3976 0 0 6621 0 7025 0 0 

and if you want to know when you started you just look at the timestamp
on the start.out file:

	$ ls -l start.out

I.e. this is definitely _not_ a job for a kernel hacker!  :-)


> -w wait just shows you the difference with the last display. You can't track
> how the counters increase with that.

Well it depends on how you look at it.  Every time the headers are shown
again (every 24 lines by default) the new absolute count is also shown:

$ netstat -i -I tlp0 -w 1 
 tlp0 in       tlp0 out              total in      total out            
 packets  errs  packets  errs colls   packets  errs  packets  errs colls
13198397     1 17718248     4     0  25535533     1 30055385     4     0
      11     0       15     0     0        11     0       15     0     0
      37     0       37     0     0        37     0       37     0     0
      34     0       31     0     0        34     0       31     0     0
      37     0       35     0     0        37     0       35     0     0
      46     0       45     0     0        46     0       45     0     0
      58     0       55     0     0       101     0       98     0     0
     137     0      133     0     0       249     0      245     0     0
      48     0       55     0     0        48     0       55     0     0
      57     0       76     0     0        57     0       76     0     0
      75     0       77     0     0       156     0      158     0     0
      41     0       41     0     0        41     0       41     0     0
      35     0       36     0     0        35     0       36     0     0
      56     0       60     0     0        87     0       91     0     0
      24     0       27     0     0        24     0       27     0     0
      96     0      132     0     0        96     0      132     0     0
     108     0      155     0     0       122     0      169     0     0
     105     0      142     0     0       106     0      143     0     0
      81     0      110     0     0        81     0      110     0     0
      26     0       34     0     0        26     0       34     0     0
      19     0       28     0     0        43     0       52     0     0
 tlp0 in       tlp0 out              total in      total out            
 packets  errs  packets  errs colls   packets  errs  packets  errs colls
13199537     1 17719589     4     0  25536979     1 30057032     4     0
      17     0       19     0     0        17     0       19     0     0
      85     0       88     0     0       191     0      194     0     0
      36     0       37     0     0        36     0       37     0     0
      14     0       19     0     0        14     0       19     0     0
     138     0      146     0     0       433     0      441     0     0
^?


Index: main.c
===================================================================
RCS file: /cvs/master/m-NetBSD/main/src/usr.bin/netstat/main.c,v
retrieving revision 1.34
diff -c -u -r1.34 main.c
--- main.c	18 Oct 2001 09:26:16 -0000	1.34
+++ main.c	13 Apr 2003 19:47:11 -0000
@@ -330,9 +330,11 @@
 	(void)setegid(getgid());
 	tp = NULL;
 	af = AF_UNSPEC;
+	count = 0;
+	interval = 0;
 	pcbaddr = 0;
 
-	while ((ch = getopt(argc, argv, "Aabdf:ghI:LliM:mN:nP:p:rsStuvw:")) != -1)
+	while ((ch = getopt(argc, argv, "Aabc:df:ghI:LliM:mN:nP:p:rsStuvw:")) != -1)
 		switch(ch) {
 		case 'A':
 			Aflag = 1;
@@ -343,6 +345,11 @@
 		case 'b':
 			bflag = 1;
 			break;
+		case 'c':
+			count = strtoul(optarg, &cp, 10);
+			if (*cp != '\0' || errno == ERANGE)
+				errx(1, "invalid count %s", optarg);
+			break;
 		case 'd':
 			dflag = 1;
 			break;
@@ -458,6 +465,9 @@
 	}
 #endif
 
+	if (count & !interval)
+		usage();
+
 	/*
 	 * Discard setgid privileges.  If not the running kernel, we toss
 	 * them away totally so that bad guys can't print interesting stuff
@@ -729,7 +739,7 @@
 "       %s [-gimnrsSv] [-f address_family] [-M core] [-N system]\n", 
 	progname);
 	(void)fprintf(stderr,
-"       %s [-n] [-I interface] [-M core] [-N system] [-w wait]\n", progname);
+"       %s [-n] [-I interface] [-M core] [-N system] [-w wait [-c count]]\n", progname);
 	(void)fprintf(stderr,
 "       %s [-M core] [-N system] [-p protocol]\n", progname);
 	(void)fprintf(stderr,
Index: if.c
===================================================================
RCS file: /cvs/master/m-NetBSD/main/src/usr.bin/netstat/if.c,v
retrieving revision 1.49
diff -c -u -r1.49 if.c
--- if.c	6 Oct 2001 18:48:30 -0000	1.49
+++ if.c	13 Apr 2003 19:50:54 -0000
@@ -419,6 +419,7 @@
 	struct iftot *lastif, *sum, *interesting;
 	struct ifnet_head ifhead;	/* TAILQ_HEAD */
 	int oldmask;
+	int lc = count;
 
 	/*
 	 * Find the pointer to the first ifnet structure.  Replace
@@ -593,6 +594,8 @@
 	putchar('\n');
 	fflush(stdout);
 	line++;
+	if (count && --lc <= 0)
+		return;
 	oldmask = sigblock(sigmask(SIGALRM));
 	if (! signalled) {
 		sigpause(0);
Index: netstat.h
===================================================================
RCS file: /cvs/master/m-NetBSD/main/src/usr.bin/netstat/netstat.h,v
retrieving revision 1.24
diff -c -u -r1.24 netstat.h
--- netstat.h	27 Feb 2002 03:55:14 -0000	1.24
+++ netstat.h	13 Apr 2003 19:39:32 -0000
@@ -59,6 +59,8 @@
 
 int	interval;	/* repeat interval for i/f stats */
 
+int	count;		/* repeat count for i/f stats */
+
 char	*interface;	/* desired i/f for stats, or NULL for all i/fs */
 
 int	af;		/* address family */


-- 
								Greg A. Woods

+1 416 218-0098;            <g.a.woods@ieee.org>;           <woods@robohack.ca>
Planix, Inc. <woods@planix.com>; VE3TCP; Secrets of the Weird <woods@weird.com>