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