Package: rstatd
Version: 4.0.1-4
Severity: important

Steps to reproduce:
1. Install packages portmap, rstatd, rstat-client
2. Generate continuous inbound + outbound network traffic (ping or similar)
3. Invoke "rsysinfo localhost" repeatedly. Output shows:

System Information for: localhost
[...]
ethernet:  rx: 0   rx-err: 0
           tx: 241470   tx-err: 0    collisions: 0

Reported rx/tx values are incorrect:
- rx is constantly 0
- tx shows randomly changing values instead of accumulated traffic

Same symptoms occur when monitoring with HP Loadrunner.

The attached patch - accompanied by an elaborate description - fixes the
problem. Credits to Christian Oetzel !

In our opinion - suggested by the nature of the necessary code changes -
this may be a 64bit specific problem. We didn't test on 32bit.

Regards, Thomas Koch


-- System Information:
Debian Release: 6.0.1
  APT prefers stable-updates
  APT policy: (500, 'stable-updates'), (500, 'stable')
Architecture: amd64 (x86_64)

Kernel: Linux 2.6.32-5-amd64 (SMP w/2 CPU cores)
Locale: LANG=en_US.utf8, LC_CTYPE=en_US.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages rstatd depends on:
ii  libc6                       2.11.2-10    Embedded GNU C Library:
Shared lib
ii  netbase                     4.45         Basic TCP/IP networking system
ii  openbsd-inetd [inet-superse 0.20080125-6 The OpenBSD Internet
Superserver
ii  portmap                     6.0.0-2      RPC port mapper
ii  update-inetd                4.38+nmu1    inetd configuration file
updater

rstatd recommends no packages.

rstatd suggests no packages.

-- no debconf information
diff -Naur rstatd-4.0.1/getdata.c rstatd-4.0.1/getdata.c
--- rstatd-4.0.1/getdata.c	2011-05-02 13:30:18.000000000 +0200
+++ rstatd-4.0.1/getdata.c	2011-05-02 08:41:20.000000000 +0200
@@ -243,11 +243,6 @@
 			}
 		}
 		/* skip lo interfaces */
-		stats->if_ipackets = 0;
-		stats->if_ierrors = 0;
-		stats->if_opackets = 0;
-		stats->if_oerrors = 0;
-		stats->if_collisions = 0;
 		if ((ninterfaces == 0 && strcmp(iface, "lo") != 0) ||
 			found_interface) {
 			stats->if_ipackets += if_ipackets;
@@ -277,7 +272,7 @@
 	getdata.vm = get_vm;
 
 	/* find out about the current kernel version */
-	memset(&u, sizeof(u), 0);
+	memset(&u, 0, sizeof(u));
 	uname(&u);
 	if (0 == strncmp(u.release, "2.2", 3)) {
 		getdata.disk = get_disk22;
@@ -293,13 +288,13 @@
 	/* prepare the disk patterns */
 	for (i = 0; i < PATTERNS; i++) {
 		rx[i] = (regex_t *)malloc(sizeof(regex_t));
-		memset(rx[i], sizeof(regex_t), 0);
+		memset(rx[i], 0, sizeof(regex_t));
 		regcomp(rx[i], patterns[i], REG_EXTENDED | REG_NOSUB);
 	}
 }
 
 void	getdata_collect(struct statsusers *s) {
-	memset(s, sizeof(struct statsusers), 0);
+	memset(s, 0, sizeof(struct statsusers));
 	getdata.net(s);
 	getdata.cpu(s);
 	getdata.load(s);
diff -Naur rstatd-4.0.1/rstat.x rstatd-4.0.1/rstat.x
--- rstatd-4.0.1/rstat.x	2001-08-15 04:35:56.000000000 +0200
+++ rstatd-4.0.1/rstat.x	2011-05-02 08:24:50.000000000 +0200
@@ -40,8 +40,8 @@
 const DK_NDRIVE = 4;
 
 struct rstat_timeval {
-	unsigned int tv_sec;		/* seconds */
-	unsigned int tv_usec;	/* and microseconds */
+	hyper tv_sec;		/* seconds */
+	hyper tv_usec;	/* and microseconds */
 };
 
 struct statsusers {				/* RSTATVERS_USERS */
@@ -52,15 +52,15 @@
 	unsigned int v_pswpin;
 	unsigned int v_pswpout;
 	unsigned int v_intr;
-	int if_ipackets;
-	int if_ierrors;
-	int if_oerrors;
-	int if_collisions;
+	unsigned int if_ipackets;
+	unsigned int if_ierrors;
+	unsigned int if_oerrors;
+	unsigned int if_collisions;
 	unsigned int v_swtch;
 	int avenrun[3];         /* scaled by FSCALE */
 	rstat_timeval boottime;
 	rstat_timeval curtime;
-	int if_opackets;
+	unsigned int if_opackets;
 	unsigned int users;
 };
 
@@ -72,11 +72,11 @@
 	unsigned v_pswpin;
 	unsigned v_pswpout;
 	unsigned v_intr;
-	int if_ipackets;
-	int if_ierrors;
-	int if_opackets;
-	int if_oerrors;
-	int if_collisions;
+	unsigned int if_ipackets;
+	unsigned int if_ierrors;
+	unsigned int if_opackets;
+	unsigned int if_oerrors;
+	unsigned int if_collisions;
 	unsigned v_swtch;
 	long avenrun[3];
 	rstat_timeval boottime;
@@ -92,15 +92,15 @@
 	unsigned int v_pswpin;
 	unsigned int v_pswpout;
 	unsigned int v_intr;
-	int if_ipackets;
-	int if_ierrors;
-	int if_oerrors;
-	int if_collisions;
+	unsigned int if_ipackets;
+	unsigned int if_ierrors;
+	unsigned int if_oerrors;
+	unsigned int if_collisions;
 	unsigned int v_swtch;
 	int avenrun[3];         /* scaled by FSCALE */
 	rstat_timeval boottime;
 	rstat_timeval curtime;
-	int if_opackets;
+	unsigned int if_opackets;
 };
 
 struct statsswtch {			/* RSTATVERS_SWTCH */
@@ -111,14 +111,14 @@
 	unsigned int v_pswpin;
 	unsigned int v_pswpout;
 	unsigned int v_intr;
-	int if_ipackets;
-	int if_ierrors;
-	int if_oerrors;
-	int if_collisions;
+	unsigned int if_ipackets;
+	unsigned int if_ierrors;
+	unsigned int if_oerrors;
+	unsigned int if_collisions;
 	unsigned int v_swtch;
 	unsigned int avenrun[3];/* scaled by FSCALE */
 	rstat_timeval boottime;
-	int if_opackets;
+	unsigned int if_opackets;
 };
 
 struct stats {				/* RSTATVERS_ORIG */
@@ -129,11 +129,11 @@
 	unsigned int v_pswpin;
 	unsigned int v_pswpout;
 	unsigned int v_intr;
-	int if_ipackets;
-	int if_ierrors;
-	int if_oerrors;
-	int if_collisions;
-	int if_opackets;
+	unsigned int if_ipackets;
+	unsigned int if_ierrors;
+	unsigned int if_oerrors;
+	unsigned int if_collisions;
+	unsigned int if_opackets;
 };
 
 
diff -Naur rstatd-4.0.1/rsysinfo.c rstatd-4.0.1/rsysinfo.c
--- rstatd-4.0.1/rsysinfo.c	2011-05-02 13:30:18.000000000 +0200
+++ rstatd-4.0.1/rsysinfo.c	2011-05-02 08:26:34.000000000 +0200
@@ -112,7 +112,7 @@
 		host_stat->dk_xfer[0], host_stat->dk_xfer[1],
 		host_stat->dk_xfer[2], host_stat->dk_xfer[3]);
 	printf("ethernet:  rx: %u   rx-err: %u\n"
-			"           tx: %u   tx-err: %u    collisions: %d\n",
+			"           tx: %u   tx-err: %u    collisions: %u\n",
 		host_stat->if_ipackets, host_stat->if_ierrors,
 		host_stat->if_opackets, host_stat->if_oerrors,
 		host_stat->if_collisions);
In module getdata.c the permutation of second and third parameter in 
memset() calls fixed.

In function get_net() in module getdata.c while iterating over list of 
interfaces in /proc/net/dev variables were set to 0 in every iteration. 
That won't result in sum over all interfaces. The corresponding statements 
were removed.

Changed type of if_ipackets, if_opackets, if_collisions, if_ierrors, if 
oerrors from int to unsigned int
Call of gettimeofday() in function get_uptime() in modul getdata.c writes 
to member curtime of struct statsusers. In 64bit environment the types 
struct timeval expected by gettimeofday() and struct rstat_timeval (type 
of member curtime) does not fit. As a consequence of this members in struct 
statsusers following curtime get overwritten.

Introduced new local variable of type struct timeval to be used by 
gettimeofday(). Values in new variable assigned to curtime in struct 
statsusers member by member.

In printf-fomatstrings in function rsysinfo_answer_v3() in module 
rsysinfo.c substituted %d by %u where appropriate.

Calls to localtime() und gmtime() in function rsysinfo_answer_v3() in 
modul rsysinfo.c access members of type unsigned int in parameter replyp. 
This is done via typecast to time_t. In 64 bit Envrionments unsigned int 
members in parameter replyp does not fit to type time_t expected by 
localtime() and gmtime(). Therefore localtime() and gmtime will access 
bigger memory area then really taken by the parameters. So localtime() and 
gmtime() probably will return wrong results and the calculation of uptime 
will fail.

Introduced new variable of type time_t in rsysinfo_answer_v3() to hold the 
corresponding values of replyp parameter and to deliver these values to 
localtime() and gmtime() in a safe way.

Reply via email to