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