xref: /csrg-svn/old/implog/implog.c (revision 22597)
1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  */
6 
7 #ifndef lint
8 char copyright[] =
9 "@(#) Copyright (c) 1983 Regents of the University of California.\n\
10  All rights reserved.\n";
11 #endif not lint
12 
13 #ifndef lint
14 static char sccsid[] = "@(#)implog.c	5.3 (Berkeley) 06/06/85";
15 #endif not lint
16 
17 #include <stdio.h>
18 #include <signal.h>
19 #include <sgtty.h>
20 
21 #include <sys/time.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <sys/socket.h>
25 
26 #include <netinet/in.h>
27 #define	IMPLEADERS
28 #include <netimp/if_imp.h>
29 
30 #define	min(a, b)	((a) < (b) ? (a) : (b))
31 
32 u_char	buf[1024];
33 int	showdata = 1;
34 int	showcontents = 0;
35 int	follow = 0;
36 int	link = -1;
37 int	host = -1;
38 int	imp = -1;
39 int	packettype = -1;
40 extern	int errno;
41 int	log;
42 char	*logfile = "/usr/adm/implog";
43 
44 /*
45  * Socket address, internet style, with
46  * unused space taken by timestamp and packet
47  * size.
48  */
49 struct sockstamp {
50 	short	sin_family;
51 	u_short	sin_port;
52 	struct	in_addr sin_addr;
53 	time_t	sin_time;
54 	int	sin_cc;
55 };
56 struct	sockstamp from;
57 
58 main(argc, argv)
59 	char *argv[];
60 {
61 	struct stat b;
62 	int size;
63 	char *cp;
64 	int hostfrom, impfrom;
65 
66 	argc--, argv++;
67 	while (argc > 0 && argv[0][0] == '-') {
68 		if (strcmp(*argv, "-D") == 0) {
69 			showdata = 0;
70 			argv++, argc--;
71 			continue;
72 		}
73 		if (strcmp(*argv, "-f") == 0) {
74 			follow++;
75 			argv++, argc--;
76 			continue;
77 		}
78 		if (strcmp(*argv, "-c") == 0) {
79 			showcontents++;
80 			argv++, argc--;
81 			continue;
82 		}
83 		if (strcmp(*argv, "-l") == 0) {
84 			argc--, argv++;
85 			if (argc > 0) {
86 				link = atoi(*argv);
87 				argc--, argv++;
88 			} else
89 				link = IMPLINK_IP;
90 			continue;
91 		}
92 		if (strcmp(*argv, "-h") == 0) {
93 			argc--, argv++;
94 			if (argc < 1) {
95 				printf("-h: missing host #\n");
96 				exit(2);
97 			}
98 			host = atoi(*argv);
99 			argv++, argc--;
100 			continue;
101 		}
102 		if (strcmp(*argv, "-i") == 0) {
103 			argc--, argv++;
104 			if (argc < 1) {
105 				printf("-i: missing imp #\n");
106 				exit(2);
107 			}
108 			imp = atoi(*argv);
109 			argv++, argc--;
110 			continue;
111 		}
112 		if (strcmp(*argv, "-t") == 0) {
113 			argc--, argv++;;
114 			if (argc < 1) {
115 				printf("-t: missing packet type\n");
116 				exit(2);
117 			}
118 			packettype = atoi(*argv);
119 			argv++, argc--;;
120 			continue;
121 		}
122 		printf("usage: implog [ -D ] [ -c ] [ -f ] [-h #] [-i #] [ -t # ] [-l [#]] [logfile]\n");
123 		exit(2);
124 	}
125 	if (argc > 0)
126 		logfile = argv[0];
127 	log = open(logfile, 0);
128 	if (log < 0) {
129 		perror(logfile);
130 		exit(1);
131 	}
132 	fstat(log, &b);
133 	size = b.st_size;
134 again:
135 	while (read(log, (char *)&from, sizeof(from)) == sizeof(from)) {
136 		if (from.sin_family == 0) {
137 			printf("restarted: %.24s\n", ctime(&from.sin_time));
138 			continue;
139 		}
140 		if (host >= 0) {
141 			long addr = ntohs(from.sin_addr.s_addr);
142 
143 			if (IN_CLASSA(addr)) {
144 				hostfrom = ((addr>>16) & 0xFF);
145 				impfrom = addr & 0xFF;
146 			} else if (IN_CLASSB(addr)) {
147 				hostfrom = ((addr>>8) & 0xFF);
148 				impfrom = addr & 0xFF;
149 			} else {
150 				hostfrom = ((addr>>4) & 0xF);
151 				impfrom = addr & 0xF;
152 			}
153 		}
154 		if (host >= 0 && hostfrom != host) {
155 			lseek(log, from.sin_cc, 1);
156 			continue;
157 		}
158 		if (imp >= 0 && impfrom != imp) {
159 			lseek(log, from.sin_cc, 1);
160 			continue;
161 		}
162 		process(log, &from);
163 	}
164 	while (follow) {
165 		fflush(stdout);
166 		sleep(5);
167 		fstat(log, &b);
168 		if (b.st_size > size) {
169 			size = b.st_size;
170 			goto again;
171 		}
172 	}
173 }
174 
175 int	impdata(), impbadleader(), impdown(), impnoop();
176 int	imprfnm(), impincomplete(), imphostdead(), imphostunreach();
177 int	impbaddata(), impreset(), impretry(), impnotify(), imptrying();
178 int	impready(), impundef();
179 
180 struct	messages {
181 	u_char	m_type;		/* type of message */
182 	int	(*m_func)();	/* routine to process message */
183 } mtypes[] = {
184 	{ IMPTYPE_DATA,		impdata },
185 	{ IMPTYPE_BADLEADER,	impbadleader },
186 	{ IMPTYPE_DOWN,		impdown },
187 	{ IMPTYPE_NOOP,		impnoop },
188 	{ IMPTYPE_RFNM,		imprfnm },
189 	{ IMPTYPE_INCOMPLETE,	impincomplete },
190 	{ IMPTYPE_HOSTDEAD,	imphostdead },
191 	{ IMPTYPE_HOSTUNREACH,	imphostunreach },
192 	{ IMPTYPE_BADDATA,	impbaddata },
193 	{ IMPTYPE_RESET,	impreset },
194 	{ IMPTYPE_RETRY,	impretry },
195 	{ IMPTYPE_NOTIFY,	impnotify },
196 	{ IMPTYPE_TRYING,	imptrying },
197 	{ IMPTYPE_READY,	impready },
198 	{ -1,			impundef }
199 };
200 
201 /*
202  * Print a packet.
203  */
204 process(l, f)
205 	int l;
206 	struct sockstamp *f;
207 {
208 	register struct messages *mp;
209 	struct imp_leader *ip;
210 
211 	if (read(l, (char *)buf, f->sin_cc) != f->sin_cc) {
212 		perror("read");
213 		return;
214 	}
215 	ip = (struct imp_leader *)buf;
216 	ip->il_imp = ntohs((u_short)ip->il_imp);
217 	for (mp = mtypes; mp->m_type != -1; mp++)
218 		if (mp->m_type == ip->il_mtype)
219 			break;
220 	if (mp->m_type == IMPTYPE_DATA) {
221 		if (link >= 0 && ip->il_link != link)
222 			return;
223 		if (!showdata)
224 			return;
225 	}
226 	if (packettype >= 0 && mp->m_type != packettype)
227 		return;
228 	printf("%.24s: ", ctime(&f->sin_time));
229 	(*mp->m_func)(ip, f->sin_cc);
230 }
231 
232 impdata(ip, cc)
233 	register struct imp_leader *ip;
234 {
235 	printf("<%d/%d, DATA, link=", ip->il_host, ntohs((u_short)ip->il_imp));
236 	if (ip->il_link == IMPLINK_IP)
237 		printf("ip,");
238 	else
239 		printf("%d,", ip->il_link);
240 	printf(" len=%d bytes>\n", ntohs((u_short)ip->il_length) >> 3);
241 	if (showcontents) {
242 		register u_char *cp = ((u_char *)ip) + sizeof(*ip);
243 		register int i;
244 
245 		i = (ntohs(ip->il_length) >> 3) - sizeof(struct imp_leader);
246 		cc = min(i, cc);
247 		printf("data: (%d bytes)", cc);
248 		for (i = 0; i < cc; i++, cp++) {
249 			if (i % 25 == 0)
250 				printf("\n");
251 			printf("%02x ", *cp);
252 		}
253 		putchar('\n');
254 	}
255 }
256 
257 char *badleader[] = {
258 	"error flip-flop set",
259 	"message < 80 bits",
260 	"illegal type field",
261 	"opposite leader type"
262 };
263 
264 impbadleader(ip)
265 	register struct imp_leader *ip;
266 {
267 	printf("bad leader: ");
268 	if (ip->il_subtype > IMPLEADER_OPPOSITE)
269 		printf("%x\n", ip->il_subtype);
270 	else
271 		printf("%s\n", badleader[ip->il_subtype]);
272 }
273 
274 char *down[] = {
275 	"in 30 secs",
276 	"for hardware pm",
277 	"for software reload",
278 	"for emergency restart"
279 };
280 
281 impdown(ip)
282 	register struct imp_leader *ip;
283 {
284 	int tdown, tbackup;
285 
286 	printf("imp going down %s", down[ip->il_link & IMP_DMASK]);
287 	tdown = ((ip->il_link >> 2) & 0xf) * 5;
288 	if (ip->il_link & IMP_DMASK)
289 		printf(" in %d minutes", tdown);
290 	tbackup = ip->il_subtype * 5;
291 	printf(": back up ");
292 	if (tbackup)
293 		printf("%d minutes\n", tbackup);
294 	else
295 		printf("immediately\n");
296 }
297 
298 impnoop(ip)
299 	register struct imp_leader *ip;
300 {
301 	printf("noop: host %d, imp %d\n", ip->il_host,
302 		ntohs((u_short)ip->il_imp));
303 }
304 
305 imprfnm(ip)
306 	register struct imp_leader *ip;
307 {
308 	printf("rfnm: htype=%x, source=%d/%d, link=",
309 		ip->il_htype, ip->il_host, ip->il_imp);
310 	if (ip->il_link == IMPLINK_IP)
311 		printf("ip,");
312 	else
313 		printf("%x,", ip->il_link);
314 	printf(" subtype=%x\n", ip->il_subtype);
315 }
316 
317 char *hostdead[] = {
318 	"#0",
319 	"ready-line negated",
320 	"tardy receiving messages",
321 	"ncc doesn't know host",
322 	"imp software won't allow messages",
323 	"host down for scheduled pm",
324 	"host down for hardware work",
325 	"host down for software work",
326 	"host down for emergency restart",
327 	"host down because of power outage",
328 	"host stopped at a breakpoint",
329 	"host down due to hardware failure",
330 	"host not scheduled to be up",
331 	"#13",
332 	"#14",
333 	"host in the process of coming up"
334 };
335 
336 imphostdead(ip)
337 	register struct imp_leader *ip;
338 {
339 	printf("host dead: ");
340 	if (ip->il_link & IMP_DMASK)
341 		printf("down %s, ", down[ip->il_link & IMP_DMASK]);
342 	if (ip->il_subtype <= IMPHOST_COMINGUP)
343 		printf("%s\n", hostdead[ip->il_subtype]);
344 	else
345 		printf("subtype=%x\n", ip->il_subtype);
346 }
347 
348 char *hostunreach[] = {
349 	"destination imp can't be reached",
350 	"destination host isn't up",
351 	"host doesn't support long leader",
352 	"communication is prohibited"
353 };
354 
355 imphostunreach(ip)
356 	register struct imp_leader *ip;
357 {
358 	printf("host unreachable: ");
359 	if (ip->il_subtype <= IMPREACH_PROHIBITED)
360 		printf("%s\n", hostunreach[ip->il_subtype]);
361 	else
362 		printf("subtype=%x\n", ip->il_subtype);
363 }
364 
365 impbaddata(ip)
366 	register struct imp_leader *ip;
367 {
368 	printf("error in data: htype=%x, source=%d/%d, link=",
369 		ip->il_htype, ip->il_host, ip->il_imp);
370 	if (ip->il_link == IMPLINK_IP)
371 		printf("ip, ");
372 	else
373 		printf("%x, ", ip->il_link);
374 	printf("subtype=%x\n", ip->il_subtype);
375 }
376 
377 char *incomplete[] = {
378 	"host didn't take data fast enough",
379 	"message was too long",
380 	"message transmission time > 15 seconds",
381 	"imp/circuit failure",
382 	"no resources within 15 seconds",
383 	"source imp i/o failure during receipt"
384 };
385 
386 impincomplete(ip)
387 	register struct imp_leader *ip;
388 {
389 	printf("incomplete: htype=%x, source=%d/%d, link=",
390 		ip->il_htype, ip->il_host, ip->il_imp);
391 	if (ip->il_link == IMPLINK_IP)
392 		printf("ip,");
393 	else
394 		printf("%x,", ip->il_link);
395 	if (ip->il_subtype <= IMPCOMPLETE_IMPIO)
396 		printf(" %s\n", incomplete[ip->il_subtype]);
397 	else
398 		printf(" subtype=%x\n", ip->il_subtype);
399 }
400 
401 impreset(ip)
402 	register struct imp_leader *ip;
403 {
404 	printf("reset complete\n");
405 }
406 
407 char *retry[] = {
408 	"imp buffer wasn't available",
409 	"connection block unavailable"
410 };
411 
412 impretry(ip)
413 	register struct imp_leader *ip;
414 {
415 	printf("refused, try again: ");
416 	if (ip->il_subtype <= IMPRETRY_BLOCK)
417 		printf("%s\n", retry[ip->il_subtype]);
418 	else
419 		printf("subtype=%x\n", ip->il_subtype);
420 }
421 
422 char *notify[] = {
423 	"#0",
424 	"#1",
425 	"connection not available",
426 	"reassembly space not available at destination",
427 	"message number not available",
428 	"transaction block for message not available"
429 };
430 
431 impnotify(ip)
432 	register struct imp_leader *ip;
433 {
434 	printf("refused, will notify: ");
435 	if (ip->il_subtype <= 5)
436 		printf("%s\n", notify[ip->il_subtype]);
437 	else
438 		printf("subtype=%x\n", ip->il_subtype);
439 }
440 
441 imptrying(ip)
442 	register struct imp_leader *ip;
443 {
444 	printf("refused, still trying\n");
445 }
446 
447 impready(ip)
448 	register struct imp_leader *ip;
449 {
450 	printf("ready\n");
451 }
452 
453 impundef(ip)
454 	register struct imp_leader *ip;
455 {
456 	printf("<fmt=%x, net=%x, flags=%x, mtype=", ip->il_format,
457 		ip->il_network, ip->il_flags);
458 	printf("%x, htype=%x, host=%x, imp=%x, link=", ip->il_mtype,
459 		ip->il_htype, ip->il_host, ip->il_imp);
460 	if (ip->il_link == IMPLINK_IP)
461 		printf("ip,");
462 	else
463 		printf("%x,", ip->il_link);
464 	printf(" subtype=%x>\n", ip->il_subtype);
465 }
466