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