Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 114694
Collapse All | Expand All

(-)netkit-rwho-0.17.old/ruptime/ruptime.c (-3 / +3 lines)
Lines 212-218 Link Here
212
	static char resbuf[32];
212
	static char resbuf[32];
213
	int days, hours, minutes;
213
	int days, hours, minutes;
214
214
215
	if (tval < 0 || tval > 999*24*60*60) {
215
	if (tval < 0) {
216
		(void)snprintf(resbuf, sizeof(resbuf), "%s     ??:??", updown);
216
		(void)snprintf(resbuf, sizeof(resbuf), "%s     ??:??", updown);
217
		return(resbuf);
217
		return(resbuf);
218
	}
218
	}
Lines 220-229 Link Here
220
	hours = minutes / 60; minutes %= 60;
220
	hours = minutes / 60; minutes %= 60;
221
	days = hours / 24; hours %= 24;
221
	days = hours / 24; hours %= 24;
222
	if (days)
222
	if (days)
223
		(void)snprintf(resbuf, sizeof(resbuf), "%s %3d+%02d:%02d",
223
		(void)snprintf(resbuf, sizeof(resbuf), "%s %4d+%02d:%02d",
224
		    updown, days, hours, minutes);
224
		    updown, days, hours, minutes);
225
	else
225
	else
226
		(void)snprintf(resbuf, sizeof(resbuf), "%s     %2d:%02d",
226
		(void)snprintf(resbuf, sizeof(resbuf), "%s      %2d:%02d",
227
		    updown, hours, minutes);
227
		    updown, hours, minutes);
228
	return(resbuf);
228
	return(resbuf);
229
}
229
}
(-)netkit-rwho-0.17.old/rwho/Makefile (-2 lines)
Lines 3-10 Link Here
3
include ../MCONFIG
3
include ../MCONFIG
4
include ../MRULES
4
include ../MRULES
5
5
6
CFLAGS += -I../include
7
8
rwho: rwho.o
6
rwho: rwho.o
9
	$(CC) $(LDFLAGS) $^ $(LIBS) -o $@
7
	$(CC) $(LDFLAGS) $^ $(LIBS) -o $@
10
8
(-)netkit-rwho-0.17.old/rwhod/Makefile (-2 / +5 lines)
Lines 3-10 Link Here
3
include ../MCONFIG
3
include ../MCONFIG
4
include ../MRULES
4
include ../MRULES
5
5
6
CFLAGS += -I../include
6
ifneq ($(USE_GLIBC),1)
7
OBJS = rwhod.o daemon.o
7
CFLAGS += -D_GNU_SOURCE
8
endif
9
10
OBJS = rwhod.o
8
11
9
rwhod: $(OBJS)
12
rwhod: $(OBJS)
10
	$(CC) $(LDFLAGS) $^ $(LIBS) -o $@
13
	$(CC) $(LDFLAGS) $^ $(LIBS) -o $@
(-)netkit-rwho-0.17.old/rwhod/rwhod.8 (-20 / +70 lines)
Lines 32-38 Link Here
32
.\"     from: @(#)rwhod.8	6.5 (Berkeley) 3/16/91
32
.\"     from: @(#)rwhod.8	6.5 (Berkeley) 3/16/91
33
.\"	$Id: rwhod.8,v 1.16 2000/07/30 23:57:06 dholland Exp $
33
.\"	$Id: rwhod.8,v 1.16 2000/07/30 23:57:06 dholland Exp $
34
.\"
34
.\"
35
.Dd May 13, 1997
35
.\" Modified by Philippe Troin <phil@fifi.org>: added interface
36
.\" options and forwarding.
37
38
.Dd March 10, 1999
36
.Dt RWHOD 8
39
.Dt RWHOD 8
37
.Os "Linux NetKit (0.17)"
40
.Os "Linux NetKit (0.17)"
38
.Sh NAME
41
.Sh NAME
Lines 40-46 Link Here
40
.Nd system status server
43
.Nd system status server
41
.Sh SYNOPSIS
44
.Sh SYNOPSIS
42
.Nm rwhod
45
.Nm rwhod
43
.Op Fl bpa
46
.Op Fl bpaf
47
.Op -i <if>...
44
.Op Fl u Ar user
48
.Op Fl u Ar user
45
.Sh DESCRIPTION
49
.Sh DESCRIPTION
46
.Nm Rwhod
50
.Nm Rwhod
Lines 67-88 Link Here
67
in the ``rwho'' service specification; see 
71
in the ``rwho'' service specification; see 
68
.Xr services 5 . 
72
.Xr services 5 . 
69
.Pp
73
.Pp
70
If the
71
.Fl b
72
flag is supplied, only broadcast interfaces, such as ethernets, will
73
be used.  
74
If the
75
.Fl p
76
flag is supplied, only point-to-point interfaces will be used. If the
77
.Fl a
78
flag is supplied, or no flags are supplied, all interfaces will be
79
used.
80
.Pp
81
If the
82
.Fl u
83
flag is supplied, rwhod will run as the specified user instead of as
84
root.
85
.Pp
86
The messages sent and received, are of the form:
74
The messages sent and received, are of the form:
87
.Bd -literal -offset indent
75
.Bd -literal -offset indent
88
struct	outmp {
76
struct	outmp {
Lines 145-160 Link Here
145
.Nm Rwhod
133
.Nm Rwhod
146
recomputes the system boot time every 30 minutes because on
134
recomputes the system boot time every 30 minutes because on
147
some (non-Linux) systems it is not a totally reliable process.
135
some (non-Linux) systems it is not a totally reliable process.
136
.Sh FLAGS
137
If the
138
.Fl b
139
flag is supplied, only broadcast interfaces, such as ethernets, will
140
be used.  
141
If the
142
.Fl p
143
flag is supplied, only point-to-point interfaces will be used. If the
144
.Fl a
145
flag is supplied, or no flags are supplied, all interfaces will be
146
used.
147
.Pp
148
Alternately, you may specify interfaces by name by providing one or
149
more
150
.Fl i
151
options followed by the interface name.
152
.Pp
153
If the
154
.Fl u
155
flag is supplied, rwhod will run as the specified user instead of as
156
root.
157
.Pp
158
.Nm Rwhod
159
can also forward packets between interfaces if started with
160
.Fl f.
161
Please read the
162
.Xr CAVEATS
163
section before enabling
164
.Xr rwhod
165
forwarding.
166
.Sh CAVEATS
167
While 
168
.Xr rwhod
169
listens on any interface present on the host, it will only send (or
170
forward) to the interfaces determined by the 
171
.Fl a b p i
172
flags.
173
.Pp
174
When operating in forwarding mode (with
175
.Fl f
176
), 
177
.Xr rwhod
178
forwards all correct rwhod packets received on an interface to all the
179
other interfaces. You can create a broadcast storm if there is a
180
loop in your network and all the routers in the loop run in forwarding
181
mode. To prevent this from happenning,
182
.Xr rwhod
183
will shut down forwarding (and log the event to the syslog) if more
184
than one 
185
.Xr rwhod
186
packet is forwarded per second on average over the last three
187
minutes. If this happens, you must break the loop of forwarding routers.
148
.Sh SEE ALSO
188
.Sh SEE ALSO
149
.Xr rwho 1 ,
189
.Xr rwho 1 ,
150
.Xr ruptime 1
190
.Xr ruptime 1
151
.Sh BUGS
191
.Sh BUGS
152
There should be a way to relay status information between networks. 
192
Some kind of proxying feature might be useful if your router doesn't
193
run
194
.Xr rwhod.
195
.Pp
153
People often interpret the server dying
196
People often interpret the server dying
154
or network communtication failures
197
or network communication failures
155
as a machine going down.
198
as a machine going down.
199
.Pp
200
.Xr Rwhod
201
doesn't refresh its interface list, which might be useful when using
202
.Fl a b p.
156
.Sh HISTORY
203
.Sh HISTORY
157
The
204
The
158
.Nm
205
.Nm
159
command appeared in
206
command appeared in
160
.Bx 4.2 .
207
.Bx 4.2 .
208
.Pp
209
Philippe Troin <phil@fifi.org> implemented forwarding and interface
210
selection flags.
(-)netkit-rwho-0.17.old/rwhod/rwhod.c (-91 / +341 lines)
Lines 29-34 Link Here
29
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31
 * SUCH DAMAGE.
31
 * SUCH DAMAGE.
32
33
 * Modified by Philippe Troin <phil@fifi.org> (added options & implemented 
34
 * them.
35
32
 */
36
 */
33
37
34
char copyright[] =
38
char copyright[] =
Lines 47-52 Link Here
47
#include <signal.h>
51
#include <signal.h>
48
#include <sys/ioctl.h>
52
#include <sys/ioctl.h>
49
#include <sys/file.h>
53
#include <sys/file.h>
54
#include <sys/types.h>
50
55
51
#include <net/if.h>
56
#include <net/if.h>
52
#include <netinet/in.h>
57
#include <netinet/in.h>
Lines 71-80 Link Here
71
#include <grp.h>
76
#include <grp.h>
72
#include <time.h>
77
#include <time.h>
73
78
74
#include "daemon.h"
75
76
#include "../version.h"
79
#include "../version.h"
77
80
81
typedef struct sockaddr_in SA;
82
78
#define ENDIAN	LITTLE_ENDIAN
83
#define ENDIAN	LITTLE_ENDIAN
79
84
80
/*
85
/*
Lines 98-124 Link Here
98
static int	verify(const char *name);
103
static int	verify(const char *name);
99
int	getloadavg(double ptr[3], int n);
104
int	getloadavg(double ptr[3], int n);
100
105
106
107
/* This is the list of interface we want to listen on */
108
struct wanted_neigh {
109
	struct wanted_neigh *w_next;
110
  	char                *w_ifname;
111
  	enum { W_USED_NOT, W_USED_ONCE, W_USED_MULTI } w_used;
112
};
113
101
/*
114
/*
102
 * We communicate with each neighbor in
115
 * We communicate with each neighbor in
103
 * a list constructed at the time we're
116
 * a list constructed at the time we're
104
 * started up.  Neighbors are currently
117
 * started up.  Neighbors are currently
105
 * directly connected via a hardware interface.
118
 * directly connected via a hardware interface.
106
 */
119
 */
107
struct	neighbor {
120
struct neighbor {
108
	struct	neighbor *n_next;
121
	struct	neighbor *n_next;
109
	char	*n_name;		/* interface name */
122
	char	*n_name;		/* interface name */
110
	char	*n_addr;		/* who to send to */
123
	SA	*n_myaddr;              /* My address on this i/f */
124
  	SA	*n_mask;                /* Netmask on this i/f */
125
	SA	*n_dstaddr;		/* who to send to */
111
	int	n_addrlen;		/* size of address */
126
	int	n_addrlen;		/* size of address */
112
	int	n_flags;		/* should forward?, interface flags */
127
	int	n_flags;		/* should forward?, interface flags */
113
};
128
};
114
129
130
static struct wanted_neigh *wanted_neigh;
115
static struct neighbor *neighbors;
131
static struct neighbor *neighbors;
116
static struct servent *sp;
132
static struct servent *sp;
117
static int sk;
133
static int sk;
118
static int use_pointopoint = 0;
134
static int use_pointopoint;
119
static int use_broadcast = 0;
135
static int use_broadcast;
120
static int need_init = 1;
136
static int need_init = 1;
121
static int child_pid = 0;
137
static int child_pid;
138
static int use_forwarding;
139
static int forwarded_packets;
140
141
/* Max number of packets to forward between each alarm() tick.
142
   If this number is exceeded, then the forwarding is switched off. */
143
#define MAX_FWD_PACKETS (AL_INTERVAL)
122
144
123
#define WHDRSIZE	(((caddr_t) &((struct whod *) 0)->wd_we) \
145
#define WHDRSIZE	(((caddr_t) &((struct whod *) 0)->wd_we) \
124
			- ((caddr_t) 0))
146
			- ((caddr_t) 0))
Lines 127-150 Link Here
127
static void termhandler(int);
149
static void termhandler(int);
128
static void sendpacket(struct whod *);
150
static void sendpacket(struct whod *);
129
static void getboottime(struct whod *);
151
static void getboottime(struct whod *);
152
static void forward(const SA *, const struct whod *, int cc);
153
static void usage(void);
130
154
131
int
155
int
132
main(int argc, char *argv[])
156
main(int argc, char *argv[])
133
{
157
{
158
  	struct wanted_neigh *wn;
159
	int wn_dup;
134
	struct sockaddr_in from;
160
	struct sockaddr_in from;
135
	struct passwd *pw = 0;
161
	struct passwd *pw;
136
	struct stat st;
162
	struct stat st;
137
	char path[64];
163
	char path[64];
138
	char *user = NULL;
164
	char *user = NULL;
139
	int on = 1;
165
	int on = 1;
140
	int opt;
166
	int opt;
167
	time_t before;
141
168
142
	if (getuid()) {
169
	if (getuid()) {
143
		fprintf(stderr, "rwhod: not super user\n");
170
		fprintf(stderr, "rwhod: not super user\n");
171
	}
172
	openlog("rwhod", LOG_PID, LOG_DAEMON);
173
	sp = getservbyname("who", "udp");
174
	if (sp == 0) {
175
		fprintf(stderr, "rwhod: udp/who: unknown service\n");
176
		exit(1);
177
	}
178
	if ((sk = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
179
		syslog(LOG_ERR, "socket: %m");
180
		exit(1);
181
	}
182
	if (setsockopt(sk, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
183
		syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
184
		exit(1);
185
	}
186
	sine.sin_family = AF_INET;
187
	sine.sin_port = sp->s_port;
188
	if (bind(sk, (struct sockaddr *)&sine, sizeof(sine)) < 0) {
189
		syslog(LOG_ERR, "bind: %m");
144
		exit(1);
190
		exit(1);
145
	}
191
	}
146
192
147
	while ((opt = getopt(argc, argv, "bpau:")) != EOF) {
193
	while ((opt = getopt(argc, argv, "bpai:fu:")) != EOF) {
148
	    switch (opt) {
194
	    switch (opt) {
149
	      case 'b':
195
	      case 'b':
150
		  use_broadcast = 1;
196
		  use_broadcast = 1;
Lines 156-184 Link Here
156
		  use_broadcast = 1;
202
		  use_broadcast = 1;
157
		  use_pointopoint = 1;
203
		  use_pointopoint = 1;
158
		  break;
204
		  break;
205
	      case 'f':
206
		  use_forwarding = 1;
207
		  break;
208
	      case 'i':
209
		  wn_dup = 0;
210
		  for (wn = wanted_neigh; wn; wn = wn->w_next) {
211
			if (strcmp(wn->w_ifname, optarg)== 0) {
212
				wn_dup = 1;
213
				break;
214
			}
215
		  }
216
		  if (wn_dup) {
217
			fprintf(stderr, "rwhod: warning: "
218
				"duplicate interface %s in arguments\n",
219
				optarg);
220
		  } else {
221
			wn = malloc(sizeof(struct wanted_neigh));
222
			if (wn == NULL) {
223
				fprintf(stderr, "rwhod: out of memory\n");
224
				exit(2);
225
			}
226
			wn->w_next = wanted_neigh;
227
			wn->w_ifname = malloc(strlen(optarg)+1);
228
			wn->w_used = W_USED_NOT;
229
			if (wn->w_ifname == NULL) {
230
				fprintf(stderr, "rwhod: out of memory\n");
231
				exit(2);
232
			}
233
			strcpy(wn->w_ifname, optarg);
234
			wanted_neigh = wn;
235
		  }
236
		  break;
159
	      case 'u':
237
	      case 'u':
160
	      	  user = optarg;
238
	      	  user = optarg;
161
		  break;
239
		  break;
162
	      case '?':
240
	      case '?':
163
	      default:
241
	      default:
164
		  fprintf(stderr, "usage: rwhod [-bpa] [-u user]\n");
242
		  usage();
165
		  exit(1);
166
		  break;
167
	    }
243
	    }
168
	}
244
	}
169
	if (optind<argc) {
245
	if (optind<argc) {
170
	    fprintf(stderr, "usage: rwhod [-bpa] [-u user]\n");
246
		usage();
171
	    exit(1);
172
	}
247
	}
173
	if (!use_pointopoint && !use_broadcast) {
248
	if (!use_pointopoint && !use_broadcast && !wanted_neigh) {
174
		/* use none is nonsensical; default to all */
249
		/* use none is nonsensical; default to all */
175
		use_pointopoint = 1;
250
		use_pointopoint = 1;
176
		use_broadcast = 1;
251
		use_broadcast = 1;
177
	}
252
	}
178
	
253
	if ((use_pointopoint || use_broadcast) && wanted_neigh) {
179
	sp = getservbyname("who", "udp");
254
		fprintf(stderr, "rwhod: cannot specify both -i and one of -b "
180
	if (sp == 0) {
255
			"-p -a\n");
181
		fprintf(stderr, "rwhod: udp/who: unknown service\n");
182
		exit(1);
256
		exit(1);
183
	}
257
	}
184
#ifndef DEBUG
258
#ifndef DEBUG
Lines 190-215 Link Here
190
		exit(1);
264
		exit(1);
191
	}
265
	}
192
	(void) signal(SIGHUP, huphandler);
266
	(void) signal(SIGHUP, huphandler);
193
	openlog("rwhod", LOG_PID, LOG_DAEMON);
194
195
	if ((sk = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
196
		syslog(LOG_ERR, "socket: %m");
197
		exit(1);
198
	}
199
	if (setsockopt(sk, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
200
		syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
201
		exit(1);
202
	}
203
	sine.sin_family = AF_INET;
204
	sine.sin_port = sp->s_port;
205
	if (bind(sk, (struct sockaddr *)&sine, sizeof(sine)) < 0) {
206
		syslog(LOG_ERR, "bind: %m");
207
		exit(1);
208
	}
209
267
210
	(void) umask(022);
268
	(void) umask(022);
211
269
212
	signal(SIGTERM, termhandler);
270
	signal(SIGTERM, termhandler);
271
272
	if (user) {
273
		/* We have to drop privs in two steps--first get the
274
		 * account info, then drop privs after chroot */
275
		if ((pw = getpwnam(user)) == NULL) {
276
			syslog(LOG_ERR, "unknown user: %s", user);
277
			exit(1);
278
		}
279
		
280
		/* Now drop privs */
281
		if (pw->pw_uid) {
282
			if (setgroups(1, &pw->pw_gid) < 0
283
			 || setgid(pw->pw_gid) < 0
284
			 || setuid(pw->pw_uid) < 0) {
285
				syslog(LOG_ERR,"failed to drop privilege: %m");
286
				exit(1);
287
			}
288
		}
289
	}
290
291
	if (!configure(sk))
292
		exit(1);
293
213
	child_pid = fork();
294
	child_pid = fork();
214
	if (child_pid < 0) {
295
	if (child_pid < 0) {
215
		syslog(LOG_ERR, "fork: %m");
296
		syslog(LOG_ERR, "fork: %m");
Lines 220-254 Link Here
220
		exit(0);
301
		exit(0);
221
	}
302
	}
222
303
223
	/* We have to drop privs in two steps--first get the
304
	before = 0;
224
	 * account info, then drop privs after chroot */
225
	if (user && (pw = getpwnam(user)) == NULL) {
226
		syslog(LOG_ERR, "unknown user: %s", user);
227
		exit(1);
228
	}
229
230
	/* Chroot to the spool directory
231
	 * (note this is already our $cwd) */
232
	if (chroot(_PATH_RWHODIR) < 0) {
233
		syslog(LOG_ERR, "chroot(%s): %m", _PATH_RWHODIR);
234
		kill(child_pid, SIGTERM);
235
		exit(1);
236
	}
237
238
	/* Now drop privs */
239
	if (pw) {
240
		if (setgroups(1, &pw->pw_gid) < 0
241
		 || setgid(pw->pw_gid) < 0
242
		 || setuid(pw->pw_uid) < 0) {
243
			syslog(LOG_ERR, "failed to drop privilege: %m");
244
			exit(1);
245
		}
246
	}
247
248
	for (;;) {
305
	for (;;) {
249
		struct whod wd;
306
		struct whod wd;
250
		int cc, whod;
307
		int cc, whod;
308
#ifdef __GLIBC__
309
		socklen_t len = sizeof(from);
310
#else
251
		size_t len = sizeof(from);
311
		size_t len = sizeof(from);
312
#endif
252
313
253
		memset(&wd, 0, sizeof(wd));
314
		memset(&wd, 0, sizeof(wd));
254
		cc = recvfrom(sk, (char *)&wd, sizeof(struct whod), 0,
315
		cc = recvfrom(sk, (char *)&wd, sizeof(struct whod), 0,
Lines 262-267 Link Here
262
			syslog(LOG_WARNING, "packet too small");
323
			syslog(LOG_WARNING, "packet too small");
263
			continue;
324
			continue;
264
		}
325
		}
326
		if (cc < WHDRSIZE) {
327
			syslog(LOG_WARNING, "packet too small");
328
			continue;
329
		}
330
		if (cc < WHDRSIZE)
331
			continue;
265
		if (from.sin_port != sp->s_port) {
332
		if (from.sin_port != sp->s_port) {
266
			syslog(LOG_WARNING, "%d: bad from port",
333
			syslog(LOG_WARNING, "%d: bad from port",
267
				ntohs(from.sin_port));
334
				ntohs(from.sin_port));
Lines 271-284 Link Here
271
			continue;
338
			continue;
272
		if (wd.wd_type != WHODTYPE_STATUS)
339
		if (wd.wd_type != WHODTYPE_STATUS)
273
			continue;
340
			continue;
341
342
		if (use_forwarding) {
343
			time_t now = time(NULL);
344
			if ((uintmax_t) (now - before) >= AL_INTERVAL) {
345
				before = now;
346
				forwarded_packets = 0;
347
			}
348
			forward(&from, &wd, cc);
349
		}
350
274
		/* 
351
		/* 
275
		 * Ensure null termination of the name within the packet.
352
		 * Ensure null termination of the name within the packet.
276
		 * Otherwise we might overflow or read past the end.
353
		 * Otherwise we might overflow or read past the end.
277
		 */
354
		 */
278
		wd.wd_hostname[sizeof(wd.wd_hostname)-1] = 0;
355
		wd.wd_hostname[sizeof(wd.wd_hostname)-1] = 0;
279
		if (!verify(wd.wd_hostname)) {
356
		if (!verify(wd.wd_hostname)) {
280
			syslog(LOG_WARNING, "malformed host name from %x",
357
			syslog(LOG_WARNING, "malformed host name from %s",
281
				from.sin_addr.s_addr);
358
			       inet_ntoa(from.sin_addr));
282
			continue;
359
			continue;
283
		}
360
		}
284
		snprintf(path, sizeof(path), "whod.%s", wd.wd_hostname);
361
		snprintf(path, sizeof(path), "whod.%s", wd.wd_hostname);
Lines 350-358 Link Here
350
	size_t		mynamelen;
427
	size_t		mynamelen;
351
	struct whod	mywd;
428
	struct whod	mywd;
352
429
353
	if (!configure(sk))
354
		exit(1);
355
356
	/*
430
	/*
357
	 * Establish host name as returned by system.
431
	 * Establish host name as returned by system.
358
	 */
432
	 */
Lines 362-368 Link Here
362
	}
436
	}
363
	if ((cp = index(myname, '.')) != NULL)
437
	if ((cp = index(myname, '.')) != NULL)
364
		*cp = '\0';
438
		*cp = '\0';
365
	mynamelen = strlen(myname);
439
	mynamelen = strlen(myname) + 1;
366
	if (mynamelen > sizeof(mywd.wd_hostname)) 
440
	if (mynamelen > sizeof(mywd.wd_hostname)) 
367
		mynamelen = sizeof(mywd.wd_hostname) - 1;
441
		mynamelen = sizeof(mywd.wd_hostname) - 1;
368
	strncpy(mywd.wd_hostname, myname, mynamelen);
442
	strncpy(mywd.wd_hostname, myname, mynamelen);
Lines 453-459 Link Here
453
	}
527
	}
454
	we = wd->wd_we;
528
	we = wd->wd_we;
455
	for (i = 0; i < nutmps; i++) {
529
	for (i = 0; i < nutmps; i++) {
456
		if (stat(we->we_utmp.out_line, &stb) >= 0)
530
		const char *p = we->we_utmp.out_line;
531
532
		if (!strchr(p, ':') && stat(p, &stb) >= 0)
457
			we->we_idle = htonl(now - stb.st_atime);
533
			we->we_idle = htonl(now - stb.st_atime);
458
		we++;
534
		we++;
459
	}
535
	}
Lines 465-474 Link Here
465
	wd->wd_vers = WHODVERSION;
541
	wd->wd_vers = WHODVERSION;
466
	wd->wd_type = WHODTYPE_STATUS;
542
	wd->wd_type = WHODTYPE_STATUS;
467
	for (np = neighbors; np != NULL; np = np->n_next) {
543
	for (np = neighbors; np != NULL; np = np->n_next) {
468
		if (sendto(sk, (char *)wd, cc, 0,
544
		if (sendto(sk, wd, cc, 0,
469
			   (struct sockaddr *) np->n_addr, np->n_addrlen) < 0) 
545
			   (struct sockaddr *) np->n_dstaddr, np->n_addrlen) < 0) 
470
		  syslog(LOG_ERR, "sendto(%s): %m",
546
		  syslog(LOG_ERR, "sendto(%s): %m",
471
			 inet_ntoa(((struct sockaddr_in *)np->n_addr)->sin_addr));
547
			 inet_ntoa(np->n_dstaddr->sin_addr));
472
	}
548
	}
473
549
474
	if (nutmps && chdir(_PATH_RWHODIR)) {
550
	if (nutmps && chdir(_PATH_RWHODIR)) {
Lines 477-482 Link Here
477
	}
553
	}
478
}
554
}
479
555
556
#if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 2)
480
/*
557
/*
481
 * Taken from:
558
 * Taken from:
482
 *
559
 *
Lines 523-528 Link Here
523
	fclose(fp);
600
	fclose(fp);
524
	return 0;
601
	return 0;
525
}
602
}
603
#endif	/* __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 2) */
526
604
527
605
528
void
606
void
Lines 571-577 Link Here
571
		exit(1);
649
		exit(1);
572
	}
650
	}
573
	(void) lseek(kmemf, (long)nl[NL_BOOTTIME].n_value, L_SET);
651
	(void) lseek(kmemf, (long)nl[NL_BOOTTIME].n_value, L_SET);
574
	(void) read(kmemf, (char *)&wd->wd_boottime,
652
	(void) read(kmemf, &wd->wd_boottime,
575
	    sizeof (wd->wd_boottime));
653
	    sizeof (wd->wd_boottime));
576
	wd->wd_boottime = htonl(wd->wd_boottime);
654
	wd->wd_boottime = htonl(wd->wd_boottime);
577
#endif
655
#endif
Lines 589-598 Link Here
589
	struct ifreq ifreq, *ifr;
667
	struct ifreq ifreq, *ifr;
590
	struct sockaddr_in *sn;
668
	struct sockaddr_in *sn;
591
	register struct neighbor *np;
669
	register struct neighbor *np;
670
	struct wanted_neigh *wn;
592
671
593
	ifc.ifc_len = sizeof (buf);
672
	ifc.ifc_len = sizeof (buf);
594
	ifc.ifc_buf = buf;
673
	ifc.ifc_buf = buf;
595
	if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
674
	if (ioctl(s, SIOCGIFCONF, &ifc) < 0) {
596
		syslog(LOG_ERR, "ioctl (get interface configuration)");
675
		syslog(LOG_ERR, "ioctl (get interface configuration)");
597
		return (0);
676
		return (0);
598
	}
677
	}
Lines 605-611 Link Here
605
#endif
684
#endif
606
	cplim = buf + ifc.ifc_len; /*skip over if's with big ifr_addr's */
685
	cplim = buf + ifc.ifc_len; /*skip over if's with big ifr_addr's */
607
	for (cp = buf; cp < cplim;
686
	for (cp = buf; cp < cplim;
687
#ifdef linux
688
			cp += sizeof(struct ifreq)) {
689
#else
608
			cp += sizeof (ifr->ifr_name) + size(ifr->ifr_addr)) {
690
			cp += sizeof (ifr->ifr_name) + size(ifr->ifr_addr)) {
691
#endif
609
		ifr = (struct ifreq *)cp;
692
		ifr = (struct ifreq *)cp;
610
		for (np = neighbors; np != NULL; np = np->n_next)
693
		for (np = neighbors; np != NULL; np = np->n_next)
611
			if (np->n_name &&
694
			if (np->n_name &&
Lines 619-681 Link Here
619
			continue;
702
			continue;
620
		np->n_name = malloc(strlen(ifr->ifr_name) + 1);
703
		np->n_name = malloc(strlen(ifr->ifr_name) + 1);
621
		if (np->n_name == NULL) {
704
		if (np->n_name == NULL) {
622
			free((char *)np);
705
			free(np);
623
			continue;
706
			continue;
624
		}
707
		}
625
		strcpy(np->n_name, ifr->ifr_name);
708
		strcpy(np->n_name, ifr->ifr_name);
626
		np->n_addrlen = sizeof (ifr->ifr_addr);
709
		np->n_addrlen = sizeof (ifr->ifr_addr);
627
		np->n_addr = malloc(np->n_addrlen);
710
628
		if (np->n_addr == NULL) {
711
		np->n_dstaddr = malloc(np->n_addrlen);
712
		if (np->n_dstaddr == NULL) {
713
			free(np->n_name);
714
			free(np);
715
			continue;
716
		}
717
		bzero(np->n_dstaddr, np->n_addrlen);
718
719
		np->n_myaddr = malloc(np->n_addrlen);
720
		if (np->n_myaddr == NULL) {
721
		        free(np->n_dstaddr);
629
			free(np->n_name);
722
			free(np->n_name);
630
			free((char *)np);
723
			free(np);
631
			continue;
724
			continue;
632
		}
725
		}
633
		bcopy((char *)&ifr->ifr_addr, np->n_addr, np->n_addrlen);
726
		bzero(np->n_myaddr, np->n_addrlen);
634
		if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
727
728
		np->n_mask = malloc(np->n_addrlen);
729
		if (np->n_mask == NULL) {
730
		        free(np->n_myaddr);
731
		        free(np->n_dstaddr);
732
			free(np->n_name);
733
			free(np);
734
			continue;
735
		}
736
		bzero(np->n_mask, np->n_addrlen);
737
738
		/* Initialize both my address and destination address by
739
		   the interface address. The destination address will be
740
		   overwritten when the interface has IFF_BROADCAST or
741
		   IFF_POINTOPOINT. */
742
		bcopy(&ifr->ifr_addr, np->n_dstaddr, np->n_addrlen);
743
		bcopy(&ifr->ifr_addr, np->n_myaddr, np->n_addrlen);
744
745
		if (ioctl(s, SIOCGIFFLAGS, &ifreq) < 0) {
635
			syslog(LOG_ERR, "ioctl (get interface flags)");
746
			syslog(LOG_ERR, "ioctl (get interface flags)");
636
			free((char *)np);
747
		        free(np->n_myaddr);
748
		        free(np->n_dstaddr);
749
			free(np->n_name);
750
			free(np);
637
			continue;
751
			continue;
638
		}
752
		}
639
		if ((ifreq.ifr_flags & IFF_UP) == 0 ||
753
		if ((ifreq.ifr_flags & IFF_UP) == 0 ||
640
		    (ifreq.ifr_flags & (IFF_BROADCAST|IFF_POINTOPOINT)) == 0) {
754
		    (ifreq.ifr_flags & (IFF_BROADCAST|IFF_POINTOPOINT)) == 0 ||
641
			free((char *)np);
755
		    (ifreq.ifr_flags & IFF_LOOPBACK) != 0) {
756
		        free(np->n_myaddr);
757
		        free(np->n_dstaddr);
758
			free(np->n_name);
759
			free(np);
642
			continue;
760
			continue;
643
		}
761
		}
762
		if (wanted_neigh) {
763
			int found = 0;
764
			for (wn = wanted_neigh; wn; wn = wn->w_next)
765
				if (strcmp(wn->w_ifname, ifreq.ifr_name)==0) {
766
					found = 1;
767
					break;
768
				}
769
			if (!found) {
770
				free(np->n_mask);
771
				free(np->n_myaddr);
772
				free(np->n_dstaddr);
773
				free(np->n_name);
774
				free(np);
775
				continue;
776
			}
777
			switch (wn->w_used) {
778
			  case W_USED_NOT:
779
			      wn->w_used = W_USED_ONCE;
780
			      break;
781
			  case W_USED_ONCE:
782
			      syslog(LOG_ERR, 
783
				     "specified interface %s more than once",
784
				     wn->w_ifname);
785
			      wn->w_used = W_USED_MULTI;
786
			      break;
787
			  case W_USED_MULTI:
788
			      /* oh well... don't tell again... */
789
			      break;
790
			  default:
791
			      syslog(LOG_CRIT, "w_used=%d on %s", 
792
				     wn->w_used, wn->w_ifname);
793
			      abort();
794
			}
795
		}
644
		np->n_flags = ifreq.ifr_flags;
796
		np->n_flags = ifreq.ifr_flags;
645
		if (np->n_flags & IFF_POINTOPOINT) {
797
		if (np->n_flags & IFF_POINTOPOINT) {
646
			if (ioctl(s, SIOCGIFDSTADDR, (char *)&ifreq) < 0) {
798
			if (ioctl(s, SIOCGIFDSTADDR, &ifreq) < 0) {
647
				syslog(LOG_ERR, "ioctl (get dstaddr)");
799
				syslog(LOG_ERR, "ioctl (get dstaddr)");
800
				free(np->n_mask);
801
				free(np->n_myaddr);
802
				free(np->n_dstaddr);
803
				free(np->n_name);
648
				free(np);
804
				free(np);
649
				continue;
805
				continue;
650
			}
806
			}
651
			if (!use_pointopoint) {
807
			if (!wanted_neigh && !use_pointopoint) {
808
			        free(np->n_mask);
809
			        free(np->n_myaddr);
810
				free(np->n_dstaddr);
811
				free(np->n_name);
652
				free(np);
812
				free(np);
653
				continue;
813
				continue;
654
			}
814
			}
655
			/* we assume addresses are all the same size */
815
			/* we assume addresses are all the same size */
656
			bcopy((char *)&ifreq.ifr_dstaddr,
816
			bcopy(&ifreq.ifr_dstaddr, np->n_dstaddr, np->n_addrlen);
657
			  np->n_addr, np->n_addrlen);
658
		}
817
		}
659
		if (np->n_flags & IFF_BROADCAST) {
818
		if (np->n_flags & IFF_BROADCAST) {
660
			if (ioctl(s, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
819
			if (ioctl(s, SIOCGIFBRDADDR, &ifreq) < 0) {
661
				syslog(LOG_ERR, "ioctl (get broadaddr)");
820
				syslog(LOG_ERR, "ioctl (get broadaddr)");
821
				free(np->n_mask);
822
		                free(np->n_myaddr);
823
				free(np->n_dstaddr);
824
				free(np->n_name);
662
				free(np);
825
				free(np);
663
				continue;
826
				continue;
664
			}
827
			}
665
			if (!use_broadcast) {
828
			if (!wanted_neigh && !use_broadcast) {
829
			        free(np->n_mask);
830
		                free(np->n_myaddr);
831
				free(np->n_dstaddr);
832
				free(np->n_name);
666
				free(np);
833
				free(np);
667
				continue;
834
				continue;
668
			}
835
			}
669
			/* we assume addresses are all the same size */
836
			/* we assume addresses are all the same size */
670
			bcopy((char *)&ifreq.ifr_broadaddr,
837
			bcopy(&ifreq.ifr_broadaddr, np->n_dstaddr, np->n_addrlen);
671
			  np->n_addr, np->n_addrlen);
838
839
			/* Get netmask */
840
			if (ioctl(s, SIOCGIFNETMASK, &ifreq) < 0) {
841
				syslog(LOG_ERR, "ioctl (get netmask)");
842
				free(np->n_mask);
843
		                free(np->n_myaddr);
844
				free(np->n_dstaddr);
845
				free(np->n_name);
846
				free(np);
847
				continue;
848
			}
849
			bcopy((char*)&ifreq.ifr_netmask,
850
			      np->n_mask, np->n_addrlen);
672
		}
851
		}
673
		/* gag, wish we could get rid of Internet dependencies */
852
		/* gag, wish we could get rid of Internet dependencies */
674
		sn = (struct sockaddr_in *)np->n_addr;
853
		sn = (SA *)np->n_dstaddr;
675
		sn->sin_port = sp->s_port;
854
		sn->sin_port = sp->s_port;
676
		np->n_next = neighbors;
855
		np->n_next = neighbors;
677
		neighbors = np;
856
		neighbors = np;
678
	}
857
	}
858
859
	/* Check for unfound i/f */
860
	for (wn = wanted_neigh; wn; wn = wn->w_next)
861
		if (wn->w_used == W_USED_NOT)
862
			syslog(LOG_WARNING, "didn't find interface %s",
863
			       wn->w_ifname);
864
865
	/* Dump out used i/f */
866
	for (np = neighbors; np; np = np->n_next)
867
		syslog(LOG_INFO, "sending on interface %s", np->n_name);
868
679
	return (1);
869
	return (1);
680
}
870
}
681
871
Lines 697-703 Link Here
697
{
887
{
698
	register struct whod *w = (struct whod *)buf;
888
	register struct whod *w = (struct whod *)buf;
699
	register struct whoent *we;
889
	register struct whoent *we;
700
	struct sockaddr_in *sn = (struct sockaddr_in *)to;
890
	struct sockaddr_in *sn = (SA *)to;
701
	char *interval();
891
	char *interval();
702
892
703
	printf("sendto %x.%d\n", ntohl(sn->sin_addr.s_addr), ntohs(sn->sin_port));
893
	printf("sendto %x.%d\n", ntohl(sn->sin_addr.s_addr), ntohs(sn->sin_port));
Lines 751-753 Link Here
751
	return (resbuf);
941
	return (resbuf);
752
}
942
}
753
#endif
943
#endif
944
945
/* Eventually forward the packet */
946
static void
947
forward(const SA *from, const struct whod *wd, int cc)
948
{
949
	struct neighbor *np;
950
	int looped_back = 0;
951
952
	/* Scan to see if the packet was sent by us */
953
	for (np = neighbors; np != NULL; np = np->n_next) 
954
		if (from->sin_addr.s_addr ==
955
		    np->n_myaddr->sin_addr.s_addr) {
956
			looped_back = 1;
957
			break;
958
		}
959
960
	if (!looped_back) {
961
		sigset_t saved_set;
962
		sigset_t mask_set;
963
964
		sigemptyset(&mask_set);
965
		sigaddset(&mask_set, SIGALRM);
966
		sigprocmask(SIG_BLOCK, &mask_set, &saved_set);
967
968
		if (++forwarded_packets > MAX_FWD_PACKETS) {
969
			syslog(LOG_ERR, "too many forward requests, "
970
					"disabling forwarding");
971
			use_forwarding = 0;
972
		}
973
974
		sigprocmask(SIG_SETMASK, &saved_set, NULL);
975
976
		/* Re-broadcast packet on all interfaces... */
977
		for (np = neighbors; np != NULL; np = np->n_next) {
978
			/* .. but do not rebroadcast on the incoming interface */
979
			if (((np->n_flags & IFF_BROADCAST) &&
980
			     (from->sin_addr.s_addr &
981
			      np->n_mask->sin_addr.s_addr) !=
982
			     (np->n_myaddr->sin_addr.s_addr &
983
			      np->n_mask->sin_addr.s_addr)) ||
984
			    ((np->n_flags & IFF_POINTOPOINT) &&
985
			     (from->sin_addr.s_addr) !=
986
			      np->n_dstaddr->sin_addr.s_addr)) {
987
				if (sendto(sk, wd, cc, 0,
988
					   (struct sockaddr *)np->n_dstaddr, 
989
					   np->n_addrlen) < 0)
990
					syslog(LOG_ERR,
991
					       "forwarding sendto(%s): %m",
992
					       inet_ntoa(np->n_dstaddr->sin_addr));
993
			}
994
		}
995
	}
996
}
997
998
static void
999
usage()
1000
{
1001
	fprintf(stderr, "usage: rwhod [-bpaf] [-i <ifname>] [-u user]...\n");
1002
	exit(1);
1003
}

Return to bug 114694