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