1 --- netkit-rwho-0.17.orig/rwho/Makefile
2 +++ netkit-rwho-0.17/rwho/Makefile
3 @@ -3,8 +3,6 @@
4 include ../MCONFIG
5 include ../MRULES
6
7 -CFLAGS += -I../include
8 -
9 rwho: rwho.o
10 $(CC) $(LDFLAGS) $^ $(LIBS) -o $@
11
12 --- netkit-rwho-0.17.orig/ruptime/ruptime.c
13 +++ netkit-rwho-0.17/ruptime/ruptime.c
14 @@ -212,7 +212,7 @@
15 static char resbuf[32];
16 int days, hours, minutes;
17
18 - if (tval < 0 || tval > 999*24*60*60) {
19 + if (tval < 0) {
20 (void)snprintf(resbuf, sizeof(resbuf), "%s ??:??", updown);
21 return(resbuf);
22 }
23 @@ -220,10 +220,10 @@
24 hours = minutes / 60; minutes %= 60;
25 days = hours / 24; hours %= 24;
26 if (days)
27 - (void)snprintf(resbuf, sizeof(resbuf), "%s %3d+%02d:%02d",
28 + (void)snprintf(resbuf, sizeof(resbuf), "%s %4d+%02d:%02d",
29 updown, days, hours, minutes);
30 else
31 - (void)snprintf(resbuf, sizeof(resbuf), "%s %2d:%02d",
32 + (void)snprintf(resbuf, sizeof(resbuf), "%s %2d:%02d",
33 updown, hours, minutes);
34 return(resbuf);
35 }
36 --- netkit-rwho-0.17.orig/rwhod/Makefile
37 +++ netkit-rwho-0.17/rwhod/Makefile
38 @@ -3,8 +3,11 @@
39 include ../MCONFIG
40 include ../MRULES
41
42 -CFLAGS += -I../include
43 -OBJS = rwhod.o daemon.o
44 +ifneq ($(USE_GLIBC),1)
45 +CFLAGS += -D_GNU_SOURCE
46 +endif
47 +
48 +OBJS = rwhod.o
49
50 rwhod: $(OBJS)
51 $(CC) $(LDFLAGS) $^ $(LIBS) -o $@
52 --- netkit-rwho-0.17.orig/rwhod/rwhod.8
53 +++ netkit-rwho-0.17/rwhod/rwhod.8
54 @@ -32,7 +32,10 @@
55 .\" from: @(#)rwhod.8 6.5 (Berkeley) 3/16/91
56 .\" $Id: rwhod.8,v 1.16 2000/07/30 23:57:06 dholland Exp $
57 .\"
58 -.Dd May 13, 1997
59 +.\" Modified by Philippe Troin <phil@fifi.org>: added interface
60 +.\" options and forwarding.
61 +
62 +.Dd March 10, 1999
63 .Dt RWHOD 8
64 .Os "Linux NetKit (0.17)"
65 .Sh NAME
66 @@ -40,7 +43,8 @@
67 .Nd system status server
68 .Sh SYNOPSIS
69 .Nm rwhod
70 -.Op Fl bpa
71 +.Op Fl bpaf
72 +.Op -i <if>...
73 .Op Fl u Ar user
74 .Sh DESCRIPTION
75 .Nm Rwhod
76 @@ -67,22 +71,6 @@
77 in the ``rwho'' service specification; see
78 .Xr services 5 .
79 .Pp
80 -If the
81 -.Fl b
82 -flag is supplied, only broadcast interfaces, such as ethernets, will
83 -be used.
84 -If the
85 -.Fl p
86 -flag is supplied, only point-to-point interfaces will be used. If the
87 -.Fl a
88 -flag is supplied, or no flags are supplied, all interfaces will be
89 -used.
90 -.Pp
91 -If the
92 -.Fl u
93 -flag is supplied, rwhod will run as the specified user instead of as
94 -root.
95 -.Pp
96 The messages sent and received, are of the form:
97 .Bd -literal -offset indent
98 struct outmp {
99 @@ -145,16 +133,78 @@
100 .Nm Rwhod
101 recomputes the system boot time every 30 minutes because on
102 some (non-Linux) systems it is not a totally reliable process.
103 +.Sh FLAGS
104 +If the
105 +.Fl b
106 +flag is supplied, only broadcast interfaces, such as ethernets, will
107 +be used.
108 +If the
109 +.Fl p
110 +flag is supplied, only point-to-point interfaces will be used. If the
111 +.Fl a
112 +flag is supplied, or no flags are supplied, all interfaces will be
113 +used.
114 +.Pp
115 +Alternately, you may specify interfaces by name by providing one or
116 +more
117 +.Fl i
118 +options followed by the interface name.
119 +.Pp
120 +If the
121 +.Fl u
122 +flag is supplied, rwhod will run as the specified user instead of as
123 +root.
124 +.Pp
125 +.Nm Rwhod
126 +can also forward packets between interfaces if started with
127 +.Fl f.
128 +Please read the
129 +.Xr CAVEATS
130 +section before enabling
131 +.Xr rwhod
132 +forwarding.
133 +.Sh CAVEATS
134 +While
135 +.Xr rwhod
136 +listens on any interface present on the host, it will only send (or
137 +forward) to the interfaces determined by the
138 +.Fl a b p i
139 +flags.
140 +.Pp
141 +When operating in forwarding mode (with
142 +.Fl f
143 +),
144 +.Xr rwhod
145 +forwards all correct rwhod packets received on an interface to all the
146 +other interfaces. You can create a broadcast storm if there is a
147 +loop in your network and all the routers in the loop run in forwarding
148 +mode. To prevent this from happenning,
149 +.Xr rwhod
150 +will shut down forwarding (and log the event to the syslog) if more
151 +than one
152 +.Xr rwhod
153 +packet is forwarded per second on average over the last three
154 +minutes. If this happens, you must break the loop of forwarding routers.
155 .Sh SEE ALSO
156 .Xr rwho 1 ,
157 .Xr ruptime 1
158 .Sh BUGS
159 -There should be a way to relay status information between networks.
160 +Some kind of proxying feature might be useful if your router doesn't
161 +run
162 +.Xr rwhod.
163 +.Pp
164 People often interpret the server dying
165 -or network communtication failures
166 +or network communication failures
167 as a machine going down.
168 +.Pp
169 +.Xr Rwhod
170 +doesn't refresh its interface list, which might be useful when using
171 +.Fl a b p.
172 .Sh HISTORY
173 The
174 .Nm
175 command appeared in
176 .Bx 4.2 .
177 +.Pp
178 +Philippe Troin <phil@fifi.org> implemented forwarding and interface
179 +selection flags.
180 --- netkit-rwho-0.17.orig/rwhod/rwhod.c
181 +++ netkit-rwho-0.17/rwhod/rwhod.c
182 @@ -29,6 +29,10 @@
183 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
184 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
185 * SUCH DAMAGE.
186 +
187 + * Modified by Philippe Troin <phil@fifi.org> (added options & implemented
188 + * them.
189 +
190 */
191
192 char copyright[] =
193 @@ -47,6 +51,7 @@
194 #include <signal.h>
195 #include <sys/ioctl.h>
196 #include <sys/file.h>
197 +#include <sys/types.h>
198
199 #include <net/if.h>
200 #include <netinet/in.h>
201 @@ -69,11 +74,13 @@
202 #include <arpa/inet.h>
203 #include <pwd.h>
204 #include <grp.h>
205 -
206 -#include "daemon.h"
207 +#include <time.h>
208 +#include <stdint.h>
209
210 #include "../version.h"
211
212 +typedef struct sockaddr_in SA;
213 +
214 #define ENDIAN LITTLE_ENDIAN
215
216 /*
217 @@ -95,7 +102,16 @@
218 static void broadcaster(void);
219 static int configure(int s);
220 static int verify(const char *name);
221 +#if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 2)
222 static int getloadavg(double ptr[3], int n);
223 +#endif
224 +
225 +/* This is the list of interface we want to listen on */
226 +struct wanted_neigh {
227 + struct wanted_neigh *w_next;
228 + char *w_ifname;
229 + enum { W_USED_NOT, W_USED_ONCE, W_USED_MULTI } w_used;
230 +};
231
232 /*
233 * We communicate with each neighbor in
234 @@ -103,21 +119,30 @@
235 * started up. Neighbors are currently
236 * directly connected via a hardware interface.
237 */
238 -struct neighbor {
239 +struct neighbor {
240 struct neighbor *n_next;
241 char *n_name; /* interface name */
242 - char *n_addr; /* who to send to */
243 + SA *n_myaddr; /* My address on this i/f */
244 + SA *n_mask; /* Netmask on this i/f */
245 + SA *n_dstaddr; /* who to send to */
246 int n_addrlen; /* size of address */
247 int n_flags; /* should forward?, interface flags */
248 };
249
250 +static struct wanted_neigh *wanted_neigh;
251 static struct neighbor *neighbors;
252 static struct servent *sp;
253 static int sk;
254 -static int use_pointopoint = 0;
255 -static int use_broadcast = 0;
256 +static int use_pointopoint;
257 +static int use_broadcast;
258 static int need_init = 1;
259 -static int child_pid = 0;
260 +static int child_pid;
261 +static int use_forwarding;
262 +static int forwarded_packets;
263 +
264 +/* Max number of packets to forward between each alarm() tick.
265 + If this number is exceeded, then the forwarding is switched off. */
266 +#define MAX_FWD_PACKETS (AL_INTERVAL)
267
268 #define WHDRSIZE (((caddr_t) &((struct whod *) 0)->wd_we) \
269 - ((caddr_t) 0))
270 @@ -126,24 +151,48 @@
271 static void termhandler(int);
272 static void sendpacket(struct whod *);
273 static void getboottime(struct whod *);
274 +static void forward(const SA *, const struct whod *, int cc);
275 +static void usage(void);
276
277 int
278 main(int argc, char *argv[])
279 {
280 + struct wanted_neigh *wn;
281 + int wn_dup;
282 struct sockaddr_in from;
283 - struct passwd *pw = 0;
284 + struct passwd *pw;
285 struct stat st;
286 char path[64];
287 - char *user = NULL;
288 + char *user = "rwhod";
289 int on = 1;
290 int opt;
291 + time_t before;
292
293 if (getuid()) {
294 fprintf(stderr, "rwhod: not super user\n");
295 + }
296 + openlog("rwhod", LOG_PID, LOG_DAEMON);
297 + sp = getservbyname("who", "udp");
298 + if (sp == 0) {
299 + fprintf(stderr, "rwhod: udp/who: unknown service\n");
300 + exit(1);
301 + }
302 + if ((sk = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
303 + syslog(LOG_ERR, "socket: %m");
304 + exit(1);
305 + }
306 + if (setsockopt(sk, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
307 + syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
308 + exit(1);
309 + }
310 + sine.sin_family = AF_INET;
311 + sine.sin_port = sp->s_port;
312 + if (bind(sk, (struct sockaddr *)&sine, sizeof(sine)) < 0) {
313 + syslog(LOG_ERR, "bind: %m");
314 exit(1);
315 }
316
317 - while ((opt = getopt(argc, argv, "bpau:")) != EOF) {
318 + while ((opt = getopt(argc, argv, "bpai:fu:")) != EOF) {
319 switch (opt) {
320 case 'b':
321 use_broadcast = 1;
322 @@ -155,31 +204,60 @@
323 use_broadcast = 1;
324 use_pointopoint = 1;
325 break;
326 + case 'f':
327 + use_forwarding = 1;
328 + break;
329 + case 'i':
330 + wn_dup = 0;
331 + for (wn = wanted_neigh; wn; wn = wn->w_next) {
332 + if (strcmp(wn->w_ifname, optarg)== 0) {
333 + wn_dup = 1;
334 + break;
335 + }
336 + }
337 + if (wn_dup) {
338 + fprintf(stderr, "rwhod: warning: "
339 + "duplicate interface %s in arguments\n",
340 + optarg);
341 + } else {
342 + wn = malloc(sizeof(struct wanted_neigh));
343 + if (wn == NULL) {
344 + fprintf(stderr, "rwhod: out of memory\n");
345 + exit(2);
346 + }
347 + wn->w_next = wanted_neigh;
348 + wn->w_ifname = malloc(strlen(optarg)+1);
349 + wn->w_used = W_USED_NOT;
350 + if (wn->w_ifname == NULL) {
351 + fprintf(stderr, "rwhod: out of memory\n");
352 + exit(2);
353 + }
354 + strcpy(wn->w_ifname, optarg);
355 + wanted_neigh = wn;
356 + }
357 + break;
358 case 'u':
359 user = optarg;
360 break;
361 case '?':
362 default:
363 - fprintf(stderr, "usage: rwhod [-bpa] [-u user]\n");
364 - exit(1);
365 - break;
366 + usage();
367 }
368 }
369 if (optind<argc) {
370 - fprintf(stderr, "usage: rwhod [-bpa] [-u user]\n");
371 - exit(1);
372 + usage();
373 }
374 - if (!use_pointopoint && !use_broadcast) {
375 + if (!use_pointopoint && !use_broadcast && !wanted_neigh) {
376 /* use none is nonsensical; default to all */
377 use_pointopoint = 1;
378 use_broadcast = 1;
379 }
380 -
381 - sp = getservbyname("who", "udp");
382 - if (sp == 0) {
383 - fprintf(stderr, "rwhod: udp/who: unknown service\n");
384 + if ((use_pointopoint || use_broadcast) && wanted_neigh) {
385 + fprintf(stderr, "rwhod: cannot specify both -i and one of -b "
386 + "-p -a\n");
387 exit(1);
388 }
389 +
390 #ifndef DEBUG
391 daemon(1, 0);
392 #endif
393 @@ -189,53 +267,20 @@
394 exit(1);
395 }
396 (void) signal(SIGHUP, huphandler);
397 - openlog("rwhod", LOG_PID, LOG_DAEMON);
398 -
399 - if ((sk = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
400 - syslog(LOG_ERR, "socket: %m");
401 - exit(1);
402 - }
403 - if (setsockopt(sk, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
404 - syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
405 - exit(1);
406 - }
407 - sine.sin_family = AF_INET;
408 - sine.sin_port = sp->s_port;
409 - if (bind(sk, (struct sockaddr *)&sine, sizeof(sine)) < 0) {
410 - syslog(LOG_ERR, "bind: %m");
411 - exit(1);
412 - }
413
414 (void) umask(022);
415
416 signal(SIGTERM, termhandler);
417 - child_pid = fork();
418 - if (child_pid < 0) {
419 - syslog(LOG_ERR, "fork: %m");
420 - exit(1);
421 - }
422 - if (child_pid == 0) {
423 - broadcaster();
424 - exit(0);
425 - }
426
427 /* We have to drop privs in two steps--first get the
428 * account info, then drop privs after chroot */
429 - if (user && (pw = getpwnam(user)) == NULL) {
430 + if ((pw = getpwnam(user)) == NULL) {
431 syslog(LOG_ERR, "unknown user: %s", user);
432 exit(1);
433 }
434
435 - /* Chroot to the spool directory
436 - * (note this is already our $cwd) */
437 - if (chroot(_PATH_RWHODIR) < 0) {
438 - syslog(LOG_ERR, "chroot(%s): %m", _PATH_RWHODIR);
439 - kill(child_pid, SIGTERM);
440 - exit(1);
441 - }
442 -
443 /* Now drop privs */
444 - if (pw) {
445 + if (pw->pw_uid) {
446 if (setgroups(1, &pw->pw_gid) < 0
447 || setgid(pw->pw_gid) < 0
448 || setuid(pw->pw_uid) < 0) {
449 @@ -244,10 +289,28 @@
450 }
451 }
452
453 + if (!configure(sk))
454 + exit(1);
455 +
456 + child_pid = fork();
457 + if (child_pid < 0) {
458 + syslog(LOG_ERR, "fork: %m");
459 + exit(1);
460 + }
461 + if (child_pid == 0) {
462 + broadcaster();
463 + exit(0);
464 + }
465 +
466 + before = 0;
467 for (;;) {
468 struct whod wd;
469 int cc, whod;
470 +#ifdef __GLIBC__
471 + socklen_t len = sizeof(from);
472 +#else
473 size_t len = sizeof(from);
474 +#endif
475
476 memset(&wd, 0, sizeof(wd));
477 cc = recvfrom(sk, (char *)&wd, sizeof(struct whod), 0,
478 @@ -257,6 +320,8 @@
479 syslog(LOG_WARNING, "recv: %m");
480 continue;
481 }
482 + if (cc < WHDRSIZE)
483 + continue;
484 if (from.sin_port != sp->s_port) {
485 syslog(LOG_WARNING, "%d: bad from port",
486 ntohs(from.sin_port));
487 @@ -266,14 +331,24 @@
488 continue;
489 if (wd.wd_type != WHODTYPE_STATUS)
490 continue;
491 +
492 + if (use_forwarding) {
493 + time_t now = time(NULL);
494 + if ((uintmax_t) (now - before) >= AL_INTERVAL) {
495 + before = now;
496 + forwarded_packets = 0;
497 + }
498 + forward(&from, &wd, cc);
499 + }
500 +
501 /*
502 * Ensure null termination of the name within the packet.
503 * Otherwise we might overflow or read past the end.
504 */
505 wd.wd_hostname[sizeof(wd.wd_hostname)-1] = 0;
506 if (!verify(wd.wd_hostname)) {
507 - syslog(LOG_WARNING, "malformed host name from %x",
508 - from.sin_addr);
509 + syslog(LOG_WARNING, "malformed host name from %s",
510 + inet_ntoa(from.sin_addr));
511 continue;
512 }
513 snprintf(path, sizeof(path), "whod.%s", wd.wd_hostname);
514 @@ -306,7 +381,7 @@
515 }
516 #endif
517 wd.wd_recvtime = time(NULL);
518 - write(whod, (char *)&wd, cc);
519 + write(whod, &wd, cc);
520 if (fstat(whod, &st) < 0 || st.st_size > cc)
521 ftruncate(whod, cc);
522 (void) close(whod);
523 @@ -345,9 +420,6 @@
524 size_t mynamelen;
525 struct whod mywd;
526
527 - if (!configure(sk))
528 - exit(1);
529 -
530 /*
531 * Establish host name as returned by system.
532 */
533 @@ -357,7 +429,7 @@
534 }
535 if ((cp = index(myname, '.')) != NULL)
536 *cp = '\0';
537 - mynamelen = strlen(myname);
538 + mynamelen = strlen(myname) + 1;
539 if (mynamelen > sizeof(mywd.wd_hostname))
540 mynamelen = sizeof(mywd.wd_hostname);
541 strncpy(mywd.wd_hostname, myname, mynamelen);
542 @@ -448,7 +520,9 @@
543 }
544 we = wd->wd_we;
545 for (i = 0; i < nutmps; i++) {
546 - if (stat(we->we_utmp.out_line, &stb) >= 0)
547 + const char *p = we->we_utmp.out_line;
548 +
549 + if (!strchr(p, ':') && stat(p, &stb) >= 0)
550 we->we_idle = htonl(now - stb.st_atime);
551 we++;
552 }
553 @@ -460,10 +534,10 @@
554 wd->wd_vers = WHODVERSION;
555 wd->wd_type = WHODTYPE_STATUS;
556 for (np = neighbors; np != NULL; np = np->n_next) {
557 - if (sendto(sk, (char *)wd, cc, 0,
558 - (struct sockaddr *) np->n_addr, np->n_addrlen) < 0)
559 + if (sendto(sk, wd, cc, 0,
560 + (struct sockaddr *) np->n_dstaddr, np->n_addrlen) < 0)
561 syslog(LOG_ERR, "sendto(%s): %m",
562 - inet_ntoa(((struct sockaddr_in *)np->n_addr)->sin_addr));
563 + inet_ntoa(np->n_dstaddr->sin_addr));
564 }
565
566 if (nutmps && chdir(_PATH_RWHODIR)) {
567 @@ -472,6 +546,7 @@
568 }
569 }
570
571 +#if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 2)
572 /*
573 * Taken from:
574 *
575 @@ -518,6 +593,7 @@
576 fclose(fp);
577 return 0;
578 }
579 +#endif /* __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 2) */
580
581
582 void
583 @@ -566,7 +642,7 @@
584 exit(1);
585 }
586 (void) lseek(kmemf, (long)nl[NL_BOOTTIME].n_value, L_SET);
587 - (void) read(kmemf, (char *)&wd->wd_boottime,
588 + (void) read(kmemf, &wd->wd_boottime,
589 sizeof (wd->wd_boottime));
590 wd->wd_boottime = htonl(wd->wd_boottime);
591 #endif
592 @@ -584,10 +660,11 @@
593 struct ifreq ifreq, *ifr;
594 struct sockaddr_in *sn;
595 register struct neighbor *np;
596 + struct wanted_neigh *wn;
597
598 ifc.ifc_len = sizeof (buf);
599 ifc.ifc_buf = buf;
600 - if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
601 + if (ioctl(s, SIOCGIFCONF, &ifc) < 0) {
602 syslog(LOG_ERR, "ioctl (get interface configuration)");
603 return (0);
604 }
605 @@ -600,7 +677,11 @@
606 #endif
607 cplim = buf + ifc.ifc_len; /*skip over if's with big ifr_addr's */
608 for (cp = buf; cp < cplim;
609 +#ifdef linux
610 + cp += sizeof(struct ifreq)) {
611 +#else
612 cp += sizeof (ifr->ifr_name) + size(ifr->ifr_addr)) {
613 +#endif
614 ifr = (struct ifreq *)cp;
615 for (np = neighbors; np != NULL; np = np->n_next)
616 if (np->n_name &&
617 @@ -614,63 +695,170 @@
618 continue;
619 np->n_name = malloc(strlen(ifr->ifr_name) + 1);
620 if (np->n_name == NULL) {
621 - free((char *)np);
622 + free(np);
623 continue;
624 }
625 strcpy(np->n_name, ifr->ifr_name);
626 np->n_addrlen = sizeof (ifr->ifr_addr);
627 - np->n_addr = malloc(np->n_addrlen);
628 - if (np->n_addr == NULL) {
629 +
630 + np->n_dstaddr = malloc(np->n_addrlen);
631 + if (np->n_dstaddr == NULL) {
632 + free(np->n_name);
633 + free(np);
634 + continue;
635 + }
636 + bzero(np->n_dstaddr, np->n_addrlen);
637 +
638 + np->n_myaddr = malloc(np->n_addrlen);
639 + if (np->n_myaddr == NULL) {
640 + free(np->n_dstaddr);
641 free(np->n_name);
642 - free((char *)np);
643 + free(np);
644 continue;
645 }
646 - bcopy((char *)&ifr->ifr_addr, np->n_addr, np->n_addrlen);
647 - if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
648 + bzero(np->n_myaddr, np->n_addrlen);
649 +
650 + np->n_mask = malloc(np->n_addrlen);
651 + if (np->n_mask == NULL) {
652 + free(np->n_myaddr);
653 + free(np->n_dstaddr);
654 + free(np->n_name);
655 + free(np);
656 + continue;
657 + }
658 + bzero(np->n_mask, np->n_addrlen);
659 +
660 + /* Initialize both my address and destination address by
661 + the interface address. The destination address will be
662 + overwritten when the interface has IFF_BROADCAST or
663 + IFF_POINTOPOINT. */
664 + bcopy(&ifr->ifr_addr, np->n_dstaddr, np->n_addrlen);
665 + bcopy(&ifr->ifr_addr, np->n_myaddr, np->n_addrlen);
666 +
667 + if (ioctl(s, SIOCGIFFLAGS, &ifreq) < 0) {
668 syslog(LOG_ERR, "ioctl (get interface flags)");
669 - free((char *)np);
670 + free(np->n_myaddr);
671 + free(np->n_dstaddr);
672 + free(np->n_name);
673 + free(np);
674 continue;
675 }
676 if ((ifreq.ifr_flags & IFF_UP) == 0 ||
677 - (ifreq.ifr_flags & (IFF_BROADCAST|IFF_POINTOPOINT)) == 0) {
678 - free((char *)np);
679 + (ifreq.ifr_flags & (IFF_BROADCAST|IFF_POINTOPOINT)) == 0 ||
680 + (ifreq.ifr_flags & IFF_LOOPBACK) != 0) {
681 + free(np->n_myaddr);
682 + free(np->n_dstaddr);
683 + free(np->n_name);
684 + free(np);
685 continue;
686 }
687 + if (wanted_neigh) {
688 + int found = 0;
689 + for (wn = wanted_neigh; wn; wn = wn->w_next)
690 + if (strcmp(wn->w_ifname, ifreq.ifr_name)==0) {
691 + found = 1;
692 + break;
693 + }
694 + if (!found) {
695 + free(np->n_mask);
696 + free(np->n_myaddr);
697 + free(np->n_dstaddr);
698 + free(np->n_name);
699 + free(np);
700 + continue;
701 + }
702 + switch (wn->w_used) {
703 + case W_USED_NOT:
704 + wn->w_used = W_USED_ONCE;
705 + break;
706 + case W_USED_ONCE:
707 + syslog(LOG_ERR,
708 + "specified interface %s more than once",
709 + wn->w_ifname);
710 + wn->w_used = W_USED_MULTI;
711 + break;
712 + case W_USED_MULTI:
713 + /* oh well... don't tell again... */
714 + break;
715 + default:
716 + syslog(LOG_CRIT, "w_used=%d on %s",
717 + wn->w_used, wn->w_ifname);
718 + abort();
719 + }
720 + }
721 np->n_flags = ifreq.ifr_flags;
722 if (np->n_flags & IFF_POINTOPOINT) {
723 - if (ioctl(s, SIOCGIFDSTADDR, (char *)&ifreq) < 0) {
724 + if (ioctl(s, SIOCGIFDSTADDR, &ifreq) < 0) {
725 syslog(LOG_ERR, "ioctl (get dstaddr)");
726 + free(np->n_mask);
727 + free(np->n_myaddr);
728 + free(np->n_dstaddr);
729 + free(np->n_name);
730 free(np);
731 continue;
732 }
733 - if (!use_pointopoint) {
734 + if (!wanted_neigh && !use_pointopoint) {
735 + free(np->n_mask);
736 + free(np->n_myaddr);
737 + free(np->n_dstaddr);
738 + free(np->n_name);
739 free(np);
740 continue;
741 }
742 /* we assume addresses are all the same size */
743 - bcopy((char *)&ifreq.ifr_dstaddr,
744 - np->n_addr, np->n_addrlen);
745 + bcopy(&ifreq.ifr_dstaddr, np->n_dstaddr, np->n_addrlen);
746 }
747 if (np->n_flags & IFF_BROADCAST) {
748 - if (ioctl(s, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
749 + if (ioctl(s, SIOCGIFBRDADDR, &ifreq) < 0) {
750 syslog(LOG_ERR, "ioctl (get broadaddr)");
751 + free(np->n_mask);
752 + free(np->n_myaddr);
753 + free(np->n_dstaddr);
754 + free(np->n_name);
755 free(np);
756 continue;
757 }
758 - if (!use_broadcast) {
759 + if (!wanted_neigh && !use_broadcast) {
760 + free(np->n_mask);
761 + free(np->n_myaddr);
762 + free(np->n_dstaddr);
763 + free(np->n_name);
764 free(np);
765 continue;
766 }
767 /* we assume addresses are all the same size */
768 - bcopy((char *)&ifreq.ifr_broadaddr,
769 - np->n_addr, np->n_addrlen);
770 + bcopy(&ifreq.ifr_broadaddr, np->n_dstaddr, np->n_addrlen);
771 +
772 + /* Get netmask */
773 + if (ioctl(s, SIOCGIFNETMASK, &ifreq) < 0) {
774 + syslog(LOG_ERR, "ioctl (get netmask)");
775 + free(np->n_mask);
776 + free(np->n_myaddr);
777 + free(np->n_dstaddr);
778 + free(np->n_name);
779 + free(np);
780 + continue;
781 + }
782 + bcopy((char*)&ifreq.ifr_netmask,
783 + np->n_mask, np->n_addrlen);
784 }
785 /* gag, wish we could get rid of Internet dependencies */
786 - sn = (struct sockaddr_in *)np->n_addr;
787 + sn = (SA *)np->n_dstaddr;
788 sn->sin_port = sp->s_port;
789 np->n_next = neighbors;
790 neighbors = np;
791 }
792 +
793 + /* Check for unfound i/f */
794 + for (wn = wanted_neigh; wn; wn = wn->w_next)
795 + if (wn->w_used == W_USED_NOT)
796 + syslog(LOG_WARNING, "didn't find interface %s",
797 + wn->w_ifname);
798 +
799 + /* Dump out used i/f */
800 + for (np = neighbors; np; np = np->n_next)
801 + syslog(LOG_INFO, "sending on interface %s", np->n_name);
802 +
803 return (1);
804 }
805
806 @@ -692,7 +880,7 @@
807 {
808 register struct whod *w = (struct whod *)buf;
809 register struct whoent *we;
810 - struct sockaddr_in *sn = (struct sockaddr_in *)to;
811 + struct sockaddr_in *sn = (SA *)to;
812 char *interval();
813
814 printf("sendto %x.%d\n", ntohl(sn->sin_addr.s_addr), ntohs(sn->sin_port));
815 @@ -746,3 +934,63 @@
816 return (resbuf);
817 }
818 #endif
819 +
820 +/* Eventually forward the packet */
821 +static void
822 +forward(const SA *from, const struct whod *wd, int cc)
823 +{
824 + struct neighbor *np;
825 + int looped_back = 0;
826 +
827 + /* Scan to see if the packet was sent by us */
828 + for (np = neighbors; np != NULL; np = np->n_next)
829 + if (from->sin_addr.s_addr ==
830 + np->n_myaddr->sin_addr.s_addr) {
831 + looped_back = 1;
832 + break;
833 + }
834 +
835 + if (!looped_back) {
836 + sigset_t saved_set;
837 + sigset_t mask_set;
838 +
839 + sigemptyset(&mask_set);
840 + sigaddset(&mask_set, SIGALRM);
841 + sigprocmask(SIG_BLOCK, &mask_set, &saved_set);
842 +
843 + if (++forwarded_packets > MAX_FWD_PACKETS) {
844 + syslog(LOG_ERR, "too many forward requests, "
845 + "disabling forwarding");
846 + use_forwarding = 0;
847 + }
848 +
849 + sigprocmask(SIG_SETMASK, &saved_set, NULL);
850 +
851 + /* Re-broadcast packet on all interfaces... */
852 + for (np = neighbors; np != NULL; np = np->n_next) {
853 + /* .. but do not rebroadcast on the incoming interface */
854 + if (((np->n_flags & IFF_BROADCAST) &&
855 + (from->sin_addr.s_addr &
856 + np->n_mask->sin_addr.s_addr) !=
857 + (np->n_myaddr->sin_addr.s_addr &
858 + np->n_mask->sin_addr.s_addr)) ||
859 + ((np->n_flags & IFF_POINTOPOINT) &&
860 + (from->sin_addr.s_addr) !=
861 + np->n_dstaddr->sin_addr.s_addr)) {
862 + if (sendto(sk, wd, cc, 0,
863 + (struct sockaddr *)np->n_dstaddr,
864 + np->n_addrlen) < 0)
865 + syslog(LOG_ERR,
866 + "forwarding sendto(%s): %m",
867 + inet_ntoa(np->n_dstaddr->sin_addr));
868 + }
869 + }
870 + }
871 +}
872 +
873 +static void
874 +usage()
875 +{
876 + fprintf(stderr, "usage: rwhod [-bpaf] [-i <ifname>] [-u user]...\n");
877 + exit(1);
878 +}
879 --- netkit-rwho-0.17.orig/debian/changelog
880 +++ netkit-rwho-0.17/debian/changelog
881 @@ -0,0 +1,122 @@
882 +netkit-rwho (0.17-8) unstable; urgency=high
883 +
884 + * Security: Check for the packet size to fix denial of service
885 + [rwhod/rwhod.c, CAN-2004-1180]. Set urgency to high due to this.
886 + Thanks Martin 'Joey' Schulze for the patch.
887 + * Changed maintainer email address.
888 +
889 + -- Alberto Gonzalez Iniesta <agi@inittab.org> Fri, 11 Feb 2005 12:39:18 +0100
890 +
891 +netkit-rwho (0.17-7) unstable; urgency=low
892 +
893 + * New Maintainer. (Closes: #249713)
894 + * Added versioned Build-Depends on debhelper.
895 + * Bumped Standards-Version to 3.6.1, no change.
896 +
897 + -- Alberto Gonzalez Iniesta <agi@agi.as> Wed, 19 May 2004 16:34:35 +0200
898 +
899 +netkit-rwho (0.17-6) unstable; urgency=low
900 +
901 + * Fixed resetting of forwarded_packets counter.
902 +
903 + -- Herbert Xu <herbert@debian.org> Sun, 27 Oct 2002 21:16:49 +1100
904 +
905 +netkit-rwho (0.17-5) unstable; urgency=low
906 +
907 + * Call configure before forking to fix forwarding (Jerome Petazzoni).
908 +
909 + -- Herbert Xu <herbert@debian.org> Sun, 1 Sep 2002 09:10:51 +1000
910 +
911 +netkit-rwho (0.17-4) unstable; urgency=low
912 +
913 + * Clean up old rwho files (Philippe Troin, closes: #114337).
914 +
915 + -- Herbert Xu <herbert@debian.org> Sat, 6 Oct 2001 12:07:44 +1000
916 +
917 +netkit-rwho (0.17-3) unstable; urgency=low
918 +
919 + * Don't stat tty devices with colons in it (closes: #95788).
920 +
921 + -- Herbert Xu <herbert@debian.org> Thu, 3 May 2001 19:27:57 +1000
922 +
923 +netkit-rwho (0.17-2) unstable; urgency=low
924 +
925 + * Fixed pointless PREREQ check that caused the arm build to fail.
926 +
927 + -- Herbert Xu <herbert@debian.org> Sat, 17 Feb 2001 22:16:14 +1100
928 +
929 +netkit-rwho (0.17-1) unstable; urgency=low
930 +
931 + * New upstream release.
932 + * Turned chroot off since it stops logging.
933 + * Fixed null termination bug with wd_hostname.
934 + * Print numbers-and-dots instead of raw IP address (Peter Maydell,
935 + closes: #77272).
936 +
937 + -- Herbert Xu <herbert@debian.org> Sun, 19 Nov 2000 19:06:59 +1100
938 +
939 +netkit-rwho (0.16-1) unstable; urgency=low
940 +
941 + * New upstream release.
942 + * Merged ruptime into the rwho package.
943 + * Run rwhod with -b by default (closes: #59981).
944 +
945 + -- Herbert Xu <herbert@debian.org> Tue, 18 Jul 2000 22:23:23 +1000
946 +
947 +netkit-rwho (0.10-8) frozen unstable; urgency=low
948 +
949 + * Fixed a typo in the init script that stopped rwhod from being restarted
950 + (closes: #51375, #59283, #59363).
951 +
952 + -- Herbert Xu <herbert@debian.org> Wed, 8 Mar 2000 15:26:32 +1100
953 +
954 +netkit-rwho (0.10-7) unstable; urgency=low
955 +
956 + * Modified init.d script so that rwhod is only started if it isn't already
957 + running (closes: #50488).
958 +
959 + -- Herbert Xu <herbert@debian.org> Thu, 18 Nov 1999 14:13:28 +1100
960 +
961 +netkit-rwho (0.10-6) unstable; urgency=low
962 +
963 + * Added a check for the existence of /usr/sbin/rwhod before trying to stop it
964 + (closes: #50186).
965 +
966 + -- Herbert Xu <herbert@debian.org> Mon, 15 Nov 1999 09:31:44 +1100
967 +
968 +netkit-rwho (0.10-5) unstable; urgency=low
969 +
970 + * Always create /var/spool/rwho in postinst (closes: #50070).
971 +
972 + -- Herbert Xu <herbert@debian.org> Sat, 13 Nov 1999 23:35:00 +1100
973 +
974 +netkit-rwho (0.10-4) unstable; urgency=low
975 +
976 + * Fixed typo in postrm, thanks to James A. Treacy (closes: #49950).
977 +
978 + -- Herbert Xu <herbert@debian.org> Fri, 12 Nov 1999 15:58:11 +1100
979 +
980 +netkit-rwho (0.10-3) unstable; urgency=low
981 +
982 + * Added dependency on adduser and passwd for rwhod (closes: #49871).
983 + * Added postrm script to remove the rwhod user upon purging.
984 + * Added preinst script to stop any running rwhod server when upgrading from
985 + netstd (closes: #49515).
986 +
987 + -- Herbert Xu <herbert@debian.org> Thu, 11 Nov 1999 19:35:22 +1100
988 +
989 +netkit-rwho (0.10-2) unstable; urgency=low
990 +
991 + * rwho now depends on rwhod.
992 +
993 + -- Herbert Xu <herbert@debian.org> Sun, 7 Nov 1999 10:26:40 +1100
994 +
995 +netkit-rwho (0.10-1) unstable; urgency=low
996 +
997 + * Initial release (closes: #46652).
998 + * Alpha fixes thanks to Bruce Murphy (closes: #39155).
999 + * Run as rwhod after binding.
1000 + * Added forwarding support with patch from Philippe Troin (closes: #43797).
1001 +
1002 + -- Herbert Xu <herbert@debian.org> Tue, 2 Nov 1999 15:45:41 +1100
1003 +
1004 --- netkit-rwho-0.17.orig/debian/copyright
1005 +++ netkit-rwho-0.17/debian/copyright
1006 @@ -0,0 +1,16 @@
1007 +This package was split from netstd by Herbert Xu herbert@debian.org on
1008 +Tue, 2 Nov 1999 14:47:51 +1100.
1009 +
1010 +netstd was created by Peter Tobias tobias@et-inf.fho-emden.de on
1011 +Wed, 20 Jul 1994 17:23:21 +0200.
1012 +
1013 +It was downloaded from ftp://ftp.uk.linux.org/pub/linux/Networking/netkit/.
1014 +
1015 +Copyright:
1016 +
1017 +Copyright (c) 1983-1991 The Regents of the University of California.
1018 +Copyright (c) 1993 Peter Eriksson, Signum Support AB
1019 +
1020 +The license can be found in /usr/share/common-licenses/BSD.
1021 +
1022 +$Id: copyright,v 1.2 2000/07/18 11:48:41 herbert Exp $
1023 --- netkit-rwho-0.17.orig/debian/rules
1024 +++ netkit-rwho-0.17/debian/rules
1025 @@ -0,0 +1,99 @@
1026 +#!/usr/bin/make -f
1027 +# GNU copyright 1997 to 1999 by Joey Hess.
1028 +# Copyright (c) 1999 Herbert Xu <herbert@debian.org>
1029 +# $Id: rules,v 1.6 2002/08/31 23:12:27 herbert Exp $
1030 +
1031 +# Uncomment this to turn on verbose mode.
1032 +#export DH_VERBOSE=1
1033 +
1034 +# This is the debhelper compatability version to use.
1035 +export DH_COMPAT=2
1036 +
1037 +# This has to be exported to make some magic below work.
1038 +export DH_OPTIONS
1039 +
1040 +build: build-stamp
1041 +build-stamp:
1042 + dh_testdir
1043 +
1044 + if [ ! -f MCONFIG ]; then \
1045 + ./configure; \
1046 + sed -e 's/^CFLAGS=\(.*\)$$/CFLAGS= -g \1/' MCONFIG \
1047 + > MCONFIG.new; \
1048 + mv MCONFIG.new MCONFIG; \
1049 + fi
1050 + $(MAKE)
1051 +
1052 + touch build-stamp
1053 +
1054 +clean:
1055 + dh_testdir
1056 + dh_testroot
1057 + rm -f build-stamp install-stamp
1058 +
1059 + -$(MAKE) distclean
1060 +
1061 + dh_clean
1062 +
1063 +install: DH_OPTIONS=
1064 +install: build install-stamp
1065 +install-stamp:
1066 + dh_testdir
1067 + dh_testroot
1068 + dh_clean -k
1069 + dh_installdirs
1070 +
1071 + install rwhod/rwhod debian/rwhod/usr/sbin
1072 + install rwho/rwho debian/rwho/usr/bin
1073 + install ruptime/ruptime debian/rwho/usr/bin
1074 + cp rwhod/rwhod.8 debian/rwhod/usr/share/man/man8
1075 + cp rwho/rwho.1 debian/rwho/usr/share/man/man1
1076 + cp ruptime/ruptime.1 debian/rwho/usr/share/man/man1
1077 +
1078 + dh_installinit -prwhod
1079 + dh_strip
1080 + touch install-stamp
1081 +
1082 +# This single target is used to build all the packages, all at once, or
1083 +# one at a time. So keep in mind: any options passed to commands here will
1084 +# affect _all_ packages. Anything you want to only affect one package
1085 +# should be put in another target, such as the install target.
1086 +binary-common:
1087 + dh_testdir
1088 + dh_testroot
1089 +# dh_installdebconf
1090 + dh_installdocs
1091 + dh_installexamples
1092 + dh_installmenu
1093 +# dh_installemacsen
1094 +# dh_installpam
1095 + dh_installcron
1096 + dh_installinfo
1097 +# dh_undocumented
1098 + dh_installchangelogs ChangeLog
1099 + dh_link
1100 + dh_compress
1101 + dh_fixperms
1102 +# dh_makeshlibs
1103 + dh_installdeb
1104 +# dh_perl
1105 + dh_shlibdeps
1106 + dh_gencontrol
1107 + dh_md5sums
1108 + dh_builddeb
1109 +
1110 +# Build architecture independant packages using the common target.
1111 +binary-indep: install
1112 +# (Uncomment this next line if you have such packages.)
1113 +# $(MAKE) -f debian/rules DH_OPTIONS=-i binary-common
1114 +
1115 +# Build architecture dependant packages using the common target.
1116 +binary-arch: install
1117 + $(MAKE) -f debian/rules DH_OPTIONS=-a binary-common
1118 +
1119 +# Any other binary targets build just one binary package at a time.
1120 +binary-%: build install
1121 + make -f debian/rules binary-common DH_OPTIONS=-p$*
1122 +
1123 +binary: binary-indep binary-arch
1124 +.PHONY: build clean binary-indep binary-arch binary install
1125 --- netkit-rwho-0.17.orig/debian/rwho.dirs
1126 +++ netkit-rwho-0.17/debian/rwho.dirs
1127 @@ -0,0 +1,2 @@
1128 +usr/bin
1129 +usr/share/man/man1
1130 --- netkit-rwho-0.17.orig/debian/rwhod.conffiles
1131 +++ netkit-rwho-0.17/debian/rwhod.conffiles
1132 @@ -0,0 +1,2 @@
1133 +/etc/cron.monthly/rwhod
1134 +/etc/init.d/rwhod
1135 --- netkit-rwho-0.17.orig/debian/rwhod.cron.monthly
1136 +++ netkit-rwho-0.17/debian/rwhod.cron.monthly
1137 @@ -0,0 +1,4 @@
1138 +#!/bin/sh
1139 +# $Id: rwhod.cron.monthly,v 1.1 2001/10/06 02:09:28 herbert Exp $
1140 +
1141 +find /var/spool/rwho -mindepth 1 -mtime +30 -print0 | xargs -r0 rm
1142 --- netkit-rwho-0.17.orig/debian/rwhod.dirs
1143 +++ netkit-rwho-0.17/debian/rwhod.dirs
1144 @@ -0,0 +1,2 @@
1145 +usr/sbin
1146 +usr/share/man/man8
1147 --- netkit-rwho-0.17.orig/debian/rwhod.docs
1148 +++ netkit-rwho-0.17/debian/rwhod.docs
1149 @@ -0,0 +1 @@
1150 +README
1151 --- netkit-rwho-0.17.orig/debian/rwhod.init
1152 +++ netkit-rwho-0.17/debian/rwhod.init
1153 @@ -0,0 +1,47 @@
1154 +#!/bin/sh -e
1155 +#
1156 +# rwhod Startup script for the rwhod server.
1157 +#
1158 +# Modified for rwhod
1159 +# by Herbert Xu <herbert@debian.org>
1160 +# Written by Miquel van Smoorenburg <miquels@cistron.nl>.
1161 +# Modified for Debian GNU/Linux
1162 +# by Ian Murdock <imurdock@gnu.ai.mit.edu>.
1163 +#
1164 +# Version: $Id: rwhod.init,v 1.5 2000/07/18 12:25:51 herbert Exp $
1165 +
1166 +DESC="System status server"
1167 +
1168 +test -x /usr/sbin/rwhod || exit 0
1169 +
1170 +start_stop() {
1171 + case "$1" in
1172 + start)
1173 + printf "Starting $DESC:"
1174 + start-stop-daemon --start --oknodo --quiet \
1175 + --exec /usr/sbin/rwhod -- -b
1176 + printf " rwhod"
1177 + printf ".\n"
1178 + ;;
1179 + stop)
1180 + printf "Stopping $DESC:"
1181 + start-stop-daemon --stop --oknodo --quiet \
1182 + --exec /usr/sbin/rwhod
1183 + printf " rwhod"
1184 + printf ".\n"
1185 + ;;
1186 + restart | force-reload)
1187 + start_stop stop
1188 + sleep 1
1189 + start_stop start
1190 + ;;
1191 + *)
1192 + printf "Usage: $0 {start|stop|restart|force-reload}\n" >&2
1193 + exit 1
1194 + ;;
1195 + esac
1196 +}
1197 +
1198 +start_stop "$@"
1199 +
1200 +exit 0
1201 --- netkit-rwho-0.17.orig/debian/rwhod.postinst
1202 +++ netkit-rwho-0.17/debian/rwhod.postinst
1203 @@ -0,0 +1,10 @@
1204 +#!/bin/sh -e
1205 +# $Id: rwhod.postinst,v 1.2 1999/11/12 22:13:05 herbert Exp $
1206 +
1207 +if ! id -u rwhod >/dev/null 2>&1; then
1208 + adduser --quiet --system --home /var/spool/rwho rwhod
1209 +fi
1210 +mkdir -p -m 755 /var/spool/rwho
1211 +chown -R rwhod /var/spool/rwho
1212 +
1213 +#DEBHELPER#
1214 --- netkit-rwho-0.17.orig/debian/rwhod.postrm
1215 +++ netkit-rwho-0.17/debian/rwhod.postrm
1216 @@ -0,0 +1,8 @@
1217 +#!/bin/sh -e
1218 +# $Id: rwhod.postrm,v 1.2 1999/11/12 04:58:48 herbert Exp $
1219 +
1220 +if [ "$1" = purge ]; then
1221 + userdel -r rwhod
1222 +fi
1223 +
1224 +#DEBHELPER#
1225 --- netkit-rwho-0.17.orig/debian/rwhod.preinst
1226 +++ netkit-rwho-0.17/debian/rwhod.preinst
1227 @@ -0,0 +1,10 @@
1228 +#!/bin/sh -e
1229 +# $Id: rwhod.preinst,v 1.2 1999/11/14 22:32:47 herbert Exp $
1230 +
1231 +# If we're upgrading from and old version of netstd, make sure that we stop
1232 +# their rwhod server if it's running.
1233 +if [ "$1" = install -a -x /etc/init.d/netstd_misc -a -x /usr/sbin/rwhod ]; then
1234 + start-stop-daemon --stop --quiet --oknodo --exec /usr/sbin/rwhod
1235 +fi
1236 +
1237 +#DEBHELPER#
1238 --- netkit-rwho-0.17.orig/debian/control
1239 +++ netkit-rwho-0.17/debian/control
1240 @@ -0,0 +1,31 @@
1241 +Source: netkit-rwho
1242 +Section: net
1243 +Priority: optional
1244 +Maintainer: Alberto Gonzalez Iniesta <agi@inittab.org>
1245 +Standards-Version: 3.6.1
1246 +Build-Depends: debhelper (>= 4.0.2)
1247 +
1248 +Package: rwhod
1249 +Architecture: any
1250 +Depends: adduser, passwd, ${shlibs:Depends}
1251 +Replaces: netstd
1252 +Description: System status server
1253 + Rwhod is the server which maintains the database used by the rwho(1)
1254 + and ruptime(1) programs. Its operation is predicated on the ability to
1255 + broadcast messages on a network.
1256 +
1257 +Package: rwho
1258 +Architecture: any
1259 +Depends: rwhod, ${shlibs:Depends}
1260 +Replaces: netstd, ruptime
1261 +Conflicts: ruptime
1262 +Description: Clients to query the rwho server
1263 + The rwho command produces output similar to who, but for all machines on
1264 + the local network. If no report has been received from a machine for 11
1265 + minutes then rwho assumes the machine is down, and does not report users
1266 + last known to be logged into that machine.
1267 + .
1268 + The ruptime command gives a status line like uptime for each machine on the
1269 + local network; these are formed from packets broadcast by each host on the
1270 + network once a minute.
1271 +
|