[net.bugs.4bsd] ruptime reports 0 users

mp@allegra.UUCP (Mark Plotnick) (11/25/85)

ruptime may claim that a machine with lots of users on it has 0 users.
This is because it reads only the first 1K bytes of a whod file into a
buffer, and assumes that it can read an array of structures backwards
from the end of the buffer.  What it gets, if the whod file is big enough,
is a bunch of garbled structures.
Here are the minimum changes necessary to stop it from getting
confused; a cleaner fix would involve rewriting it to look more like
rwho.c.

*** ruptime.1.1	Sun Nov 24 16:58:43 1985
--- ruptime.1.2	Sun Nov 24 16:58:44 1985
***************
*** 36,38
  	int f, i, t;
! 	char buf[BUFSIZ]; int cc;
  	register struct hs *hsp = hs;

--- 36,38 -----
  	int f, i, t;
! 	char buf[sizeof (struct whod)]; int cc;
  	register struct hs *hsp = hs;
***************
*** 86,88
  		if (f > 0) {
! 			cc = read(f, buf, BUFSIZ);
  			if (cc >= WHDRSIZE) {

--- 86,88 -----
  		if (f > 0) {
! 			cc = read(f, buf, sizeof buf);
  			if (cc >= WHDRSIZE) {
***************
*** 88,89
  			if (cc >= WHDRSIZE) {
  				hsp->hs_wd = (struct whod *)malloc(WHDRSIZE);

--- 88,91 -----
  			if (cc >= WHDRSIZE) {
+ 				/* first, chop off any incomplete entry */
+ 				cc -= (cc - WHDRSIZE) % sizeof (struct whoent);
  				hsp->hs_wd = (struct whod *)malloc(WHDRSIZE);

	Mark Plotnick
	Department of remote control
	allegra!mp

rsk@pucc-j (Wombat) (12/05/85)

In article <5444@allegra.UUCP> mp@allegra.UUCP (Mark Plotnick) writes:
>ruptime may claim that a machine with lots of users on it has 0 users.
>This is because it reads only the first 1K bytes of a whod file into a
>buffer, and assumes that it can read an array of structures backwards
>from the end of the buffer.  What it gets, if the whod file is big enough,
>is a bunch of garbled structures.

Mark's fix is correct, and does fix the problem with the reading of the whod
file (Thanks Mark!) but it doesn't attack the next problem, which is that
(apparently) the UDP packetsize winds up restricting the maximum number of
users that will be reported to 41; the largest file that will be created
in /usr/spool/rwho is 1044 bytes.  Gerrit Huizenga of our staff pointed out
that one of our machines had 44 users on it while "ruptime -a" insisted
that it only had 41...

Does anyone have a fix for this?
-- 
Rich Kulawiec	rsk@pur-ee.uucp rsk@purdue.uucp rsk@purdue-asc.arpa

ddl@tardis.UUCP (Dan Lanciani) (12/08/85)

	I believe this caused by the restriction that broadcast packets not
be allowed to fragment if the MTU of the interface is too small.  See
ip_output.c.  I'm not sure that this is necessary and I think I removed
it in 2.9.

						Dan Lanciani
						ddl@tardis

chris@umcp-cs.UUCP (Chris Torek) (12/08/85)

In article <629@pucc-j> rsk@pucc-j (Wombat) writes:

>In article <5444@allegra.UUCP> mp@allegra.UUCP (Mark Plotnick)

[gives a fix for a ruptime bug]

>Mark's fix is correct, and does fix the problem with the reading of
>the whod file (Thanks Mark!) but it doesn't attack the next problem,
>which is that (apparently) the UDP packetsize winds up restricting
>the maximum number of users that will be reported to 41...

Actually, at least in our kernel, the maximum datagram size is 2048
bytes.  Of course, most kernels will not allow this to be sent as
a broadcast packet, because of this statement in netinet/ip_output.c:

		if (ip->ip_len > ifp->if_mtu) {
			error = EMSGSIZE;
			goto bad;
		}

We turned this off long ago when (for reasons that are no longer
important) we had to use a tiny ETHERMTU.  Just `#ifdef notdef'
out the code and it all works again.  I guess that the reason for
the restriction was that reassembling broadcast fragments is a
great burden on every machine on the network; but broadcasts may
only be sent by the super-user, who is presumed to know what he is
doing.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@mimsy.umd.edu

kupfer@ucbvax.BERKELEY.EDU (Mike Kupfer) (12/14/85)

>>ruptime may claim that a machine with lots of users on it has 0 users.
>>This is because it reads only the first 1K bytes of a whod file into a
>>buffer, and assumes that it can read an array of structures backwards
>>from the end of the buffer.  What it gets, if the whod file is big enough,
>>is a bunch of garbled structures.

I thought about this a bit as part of my M.S. project.  I don't see the
wisdom in broadcasting multi-KB packets to all the machines on your
net, just so that everyone knows that you have 44 (rather than 41)
users.  My idea of fixing the problem is to include a flag in the
packet that says "there's more than would fit in this packet" and then
having ruptime note that the flag was set.

This implies that for heavily loaded systems rwho will leave off some
names, but I don't see that as a major hassle as long as it's not done
silently.  After all, rwho information is nice, but not especially
critical (I think), and if you have lots of users, your cycles and
network bandwidth have better things to do than tell who's logged on
across the net.

Comments, anyone?

mike
-----
Mike Kupfer
Xerox ISD (formerly at U.C. Berkeley)
kupfer.pa@xerox.ARPA
...!ucbvax!kupfer (gets forwarded)
-- 
Mike Kupfer
Xerox ISD
kupfer.pa@xerox.ARPA
...!ucbvax!kupfer (gets forwarded)

preece@ccvaxa.UUCP (12/16/85)

I'd suggest having the rwho message contain a window into the user
list, containing at most n entries per window.  After each sending
the window is advanced in the list, eventually wrapping around to
the beginning.  N is based on the max packet size.  Thus it still sends
the more important stuff (the ruptimme info) at the highest
frequency and just keeps the rwho list a little less current.
This generates less net traffic than sending the whole list,
in multiple packets, at each shot.

I think the rwho list is worth having.  A solution which just
set a flag indicating the list was too long would not be a
reasonable solution.

-- 
scott preece
gould/csd - urbana
uucp:	ihnp4!uiucdcs!ccvaxa!preece
arpa:	preece@gswd-vms