xref: /csrg-svn/old/implog/implog.c (revision 27727)
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.4 (Berkeley) 05/05/86";
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((u_short)ip->il_imp);
224 	if (ip->il_format != IMP_NFF)
225 		fn = impundef;
226 	else {
227 		for (mp = mtypes; mp->m_type != -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 	(*fn)(ip, f->sin_cc);
242 	if (rawheader && fn != impundef)
243 		impundef(ip, f->sin_cc);
244 }
245 
246 impdata(ip, cc)
247 	register struct imp_leader *ip;
248 {
249 	printf("<DATA, source=%d/%d, link=", ip->il_host, (u_short)ip->il_imp);
250 	if (ip->il_link == IMPLINK_IP)
251 		printf("ip,");
252 	else
253 		printf("%d,", ip->il_link);
254 	printf(" len=%d bytes>\n", ntohs((u_short)ip->il_length) >> 3);
255 	if (showcontents) {
256 		register u_char *cp = ((u_char *)ip) + sizeof(*ip);
257 		register int i;
258 
259 		i = (ntohs(ip->il_length) >> 3) - sizeof(struct imp_leader);
260 		cc = min(i, cc);
261 		printf("data: (%d bytes)", cc);
262 		for (i = 0; i < cc; i++, cp++) {
263 			if (i % 25 == 0)
264 				printf("\n");
265 			printf("%02x ", *cp);
266 		}
267 		putchar('\n');
268 	}
269 }
270 
271 char *badleader[] = {
272 	"error flip-flop set",
273 	"message < 80 bits",
274 	"illegal type field",
275 	"opposite leader type"
276 };
277 
278 impbadleader(ip)
279 	register struct imp_leader *ip;
280 {
281 	printf("bad leader: ");
282 	if (ip->il_subtype > IMPLEADER_OPPOSITE)
283 		printf("%x\n", ip->il_subtype);
284 	else
285 		printf("%s\n", badleader[ip->il_subtype]);
286 }
287 
288 char *down[] = {
289 	"in 30 secs",
290 	"for hardware pm",
291 	"for software reload",
292 	"for emergency restart"
293 };
294 
295 impdown(ip)
296 	register struct imp_leader *ip;
297 {
298 	int tdown, tbackup;
299 
300 	printf("imp going down %s", down[ip->il_link & IMP_DMASK]);
301 	tdown = ((ip->il_link >> 2) & 0xf) * 5;
302 	if (ip->il_link & IMP_DMASK)
303 		printf(" in %d minutes", tdown);
304 	tbackup = ip->il_subtype * 5;
305 	printf(": back up ");
306 	if (tbackup)
307 		printf("%d minutes\n", tbackup);
308 	else
309 		printf("immediately\n");
310 }
311 
312 impnoop(ip)
313 	register struct imp_leader *ip;
314 {
315 	printf("noop: host %d, imp %d\n", ip->il_host,
316 		(u_short)ip->il_imp);
317 }
318 
319 imprfnm(ip)
320 	register struct imp_leader *ip;
321 {
322 	printf("rfnm: htype=%x, source=%d/%d, link=",
323 		ip->il_htype, ip->il_host, ip->il_imp);
324 	if (ip->il_link == IMPLINK_IP)
325 		printf("ip,");
326 	else
327 		printf("%d,", ip->il_link);
328 	printf(" subtype=%x\n", ip->il_subtype);
329 }
330 
331 char *hostdead[] = {
332 	"#0",
333 	"ready-line negated",
334 	"tardy receiving messages",
335 	"ncc doesn't know host",
336 	"imp software won't allow messages",
337 	"host down for scheduled pm",
338 	"host down for hardware work",
339 	"host down for software work",
340 	"host down for emergency restart",
341 	"host down because of power outage",
342 	"host stopped at a breakpoint",
343 	"host down due to hardware failure",
344 	"host not scheduled to be up",
345 	"#13",
346 	"#14",
347 	"host in the process of coming up"
348 };
349 
350 imphostdead(ip)
351 	register struct imp_leader *ip;
352 {
353 	printf("host %d/%d dead: ", ip->il_host, ip->il_imp);
354 	if (ip->il_link & IMP_DMASK)
355 		printf("down %s, ", down[ip->il_link & IMP_DMASK]);
356 	if (ip->il_subtype <= IMPHOST_COMINGUP)
357 		printf("%s\n", hostdead[ip->il_subtype]);
358 	else
359 		printf("subtype=%x\n", ip->il_subtype);
360 }
361 
362 char *hostunreach[] = {
363 	"destination imp can't be reached",
364 	"destination host isn't up",
365 	"host doesn't support long leader",
366 	"communication is prohibited"
367 };
368 
369 imphostunreach(ip)
370 	register struct imp_leader *ip;
371 {
372 	printf("host %d/%d unreachable: ", ip->il_host, ip->il_imp);
373 	if (ip->il_subtype <= IMPREACH_PROHIBITED)
374 		printf("%s\n", hostunreach[ip->il_subtype]);
375 	else
376 		printf("subtype=%x\n", ip->il_subtype);
377 }
378 
379 impbaddata(ip)
380 	register struct imp_leader *ip;
381 {
382 	printf("error in data: htype=%x, source=%d/%d, link=",
383 		ip->il_htype, ip->il_host, ip->il_imp);
384 	if (ip->il_link == IMPLINK_IP)
385 		printf("ip, ");
386 	else
387 		printf("%d, ", ip->il_link);
388 	printf("subtype=%x\n", ip->il_subtype);
389 }
390 
391 char *incomplete[] = {
392 	"host didn't take data fast enough",
393 	"message was too long",
394 	"message transmission time > 15 seconds",
395 	"imp/circuit failure",
396 	"no resources within 15 seconds",
397 	"source imp i/o failure during receipt"
398 };
399 
400 impincomplete(ip)
401 	register struct imp_leader *ip;
402 {
403 	printf("incomplete: htype=%x, source=%d/%d, link=",
404 		ip->il_htype, ip->il_host, ip->il_imp);
405 	if (ip->il_link == IMPLINK_IP)
406 		printf("ip,");
407 	else
408 		printf("%d,", ip->il_link);
409 	if (ip->il_subtype <= IMPCOMPLETE_IMPIO)
410 		printf(" %s\n", incomplete[ip->il_subtype]);
411 	else
412 		printf(" subtype=%x\n", ip->il_subtype);
413 }
414 
415 impreset(ip)
416 	register struct imp_leader *ip;
417 {
418 	printf("reset complete\n");
419 }
420 
421 char *retry[] = {
422 	"imp buffer wasn't available",
423 	"connection block unavailable"
424 };
425 
426 impretry(ip)
427 	register struct imp_leader *ip;
428 {
429 	printf("refused, try again: ");
430 	if (ip->il_subtype <= IMPRETRY_BLOCK)
431 		printf("%s\n", retry[ip->il_subtype]);
432 	else
433 		printf("subtype=%x\n", ip->il_subtype);
434 }
435 
436 char *notify[] = {
437 	"#0",
438 	"#1",
439 	"connection not available",
440 	"reassembly space not available at destination",
441 	"message number not available",
442 	"transaction block for message not available"
443 };
444 
445 impnotify(ip)
446 	register struct imp_leader *ip;
447 {
448 	printf("refused, will notify: ");
449 	if (ip->il_subtype <= 5)
450 		printf("%s\n", notify[ip->il_subtype]);
451 	else
452 		printf("subtype=%x\n", ip->il_subtype);
453 }
454 
455 imptrying(ip)
456 	register struct imp_leader *ip;
457 {
458 	printf("refused, still trying\n");
459 }
460 
461 impready(ip)
462 	register struct imp_leader *ip;
463 {
464 	printf("ready\n");
465 }
466 
467 impundef(ip)
468 	register struct imp_leader *ip;
469 {
470 	printf("<fmt=%x, net=%x, flags=%x, mtype=", ip->il_format,
471 		ip->il_network, ip->il_flags);
472 	printf("%x, htype=%x, host=%x, imp=%x, link=", ip->il_mtype,
473 		ip->il_htype, ip->il_host, ip->il_imp);
474 	if (ip->il_link == IMPLINK_IP)
475 		printf("ip,");
476 	else
477 		printf("%d,", ip->il_link);
478 	printf(" subtype=%x>\n", ip->il_subtype);
479 }
480