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