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