xref: /csrg-svn/old/implog/implog.c (revision 22597)
121138Sdist /*
221140Sdist  * Copyright (c) 1983 Regents of the University of California.
321138Sdist  * All rights reserved.  The Berkeley software License Agreement
421138Sdist  * specifies the terms and conditions for redistribution.
521138Sdist  */
621138Sdist 
79197Ssam #ifndef lint
821138Sdist char copyright[] =
921140Sdist "@(#) Copyright (c) 1983 Regents of the University of California.\n\
1021138Sdist  All rights reserved.\n";
1121138Sdist #endif not lint
126478Ssam 
1321138Sdist #ifndef lint
14*22597Skarels static char sccsid[] = "@(#)implog.c	5.3 (Berkeley) 06/06/85";
1521138Sdist #endif not lint
1621138Sdist 
176478Ssam #include <stdio.h>
186478Ssam #include <signal.h>
196478Ssam #include <sgtty.h>
209195Ssam 
2113600Ssam #include <sys/time.h>
226478Ssam #include <sys/types.h>
236478Ssam #include <sys/stat.h>
246478Ssam #include <sys/socket.h>
259195Ssam 
269195Ssam #include <netinet/in.h>
276478Ssam #define	IMPLEADERS
289195Ssam #include <netimp/if_imp.h>
296478Ssam 
306478Ssam #define	min(a, b)	((a) < (b) ? (a) : (b))
316478Ssam 
326478Ssam u_char	buf[1024];
336478Ssam int	showdata = 1;
346478Ssam int	showcontents = 0;
356478Ssam int	follow = 0;
366478Ssam int	link = -1;
376478Ssam int	host = -1;
386478Ssam int	imp = -1;
396478Ssam int	packettype = -1;
406478Ssam extern	int errno;
416478Ssam int	log;
426478Ssam char	*logfile = "/usr/adm/implog";
436478Ssam 
446478Ssam /*
456478Ssam  * Socket address, internet style, with
466478Ssam  * unused space taken by timestamp and packet
476478Ssam  * size.
486478Ssam  */
496478Ssam struct sockstamp {
506478Ssam 	short	sin_family;
516478Ssam 	u_short	sin_port;
526478Ssam 	struct	in_addr sin_addr;
536478Ssam 	time_t	sin_time;
546478Ssam 	int	sin_cc;
556478Ssam };
566478Ssam struct	sockstamp from;
576478Ssam 
586478Ssam main(argc, argv)
596478Ssam 	char *argv[];
606478Ssam {
616478Ssam 	struct stat b;
626478Ssam 	int size;
636478Ssam 	char *cp;
64*22597Skarels 	int hostfrom, impfrom;
656478Ssam 
666478Ssam 	argc--, argv++;
676478Ssam 	while (argc > 0 && argv[0][0] == '-') {
686478Ssam 		if (strcmp(*argv, "-D") == 0) {
696478Ssam 			showdata = 0;
706478Ssam 			argv++, argc--;
716478Ssam 			continue;
726478Ssam 		}
736478Ssam 		if (strcmp(*argv, "-f") == 0) {
746478Ssam 			follow++;
756478Ssam 			argv++, argc--;
766478Ssam 			continue;
776478Ssam 		}
786478Ssam 		if (strcmp(*argv, "-c") == 0) {
796478Ssam 			showcontents++;
806478Ssam 			argv++, argc--;
816478Ssam 			continue;
826478Ssam 		}
836478Ssam 		if (strcmp(*argv, "-l") == 0) {
846478Ssam 			argc--, argv++;
856478Ssam 			if (argc > 0) {
866478Ssam 				link = atoi(*argv);
876478Ssam 				argc--, argv++;
886478Ssam 			} else
896478Ssam 				link = IMPLINK_IP;
906478Ssam 			continue;
916478Ssam 		}
926478Ssam 		if (strcmp(*argv, "-h") == 0) {
936478Ssam 			argc--, argv++;
946478Ssam 			if (argc < 1) {
956478Ssam 				printf("-h: missing host #\n");
966478Ssam 				exit(2);
976478Ssam 			}
986478Ssam 			host = atoi(*argv);
996478Ssam 			argv++, argc--;
1006478Ssam 			continue;
1016478Ssam 		}
1026478Ssam 		if (strcmp(*argv, "-i") == 0) {
1036478Ssam 			argc--, argv++;
1046478Ssam 			if (argc < 1) {
1056478Ssam 				printf("-i: missing imp #\n");
1066478Ssam 				exit(2);
1076478Ssam 			}
1086478Ssam 			imp = atoi(*argv);
1096478Ssam 			argv++, argc--;
1106478Ssam 			continue;
1116478Ssam 		}
1126478Ssam 		if (strcmp(*argv, "-t") == 0) {
1136478Ssam 			argc--, argv++;;
1146478Ssam 			if (argc < 1) {
1156478Ssam 				printf("-t: missing packet type\n");
1166478Ssam 				exit(2);
1176478Ssam 			}
1186478Ssam 			packettype = atoi(*argv);
1196478Ssam 			argv++, argc--;;
1206478Ssam 			continue;
1216478Ssam 		}
1229195Ssam 		printf("usage: implog [ -D ] [ -c ] [ -f ] [-h #] [-i #] [ -t # ] [-l [#]] [logfile]\n");
1236478Ssam 		exit(2);
1246478Ssam 	}
1256478Ssam 	if (argc > 0)
1266478Ssam 		logfile = argv[0];
1276478Ssam 	log = open(logfile, 0);
1286478Ssam 	if (log < 0) {
1296478Ssam 		perror(logfile);
1306478Ssam 		exit(1);
1316478Ssam 	}
1326478Ssam 	fstat(log, &b);
1336478Ssam 	size = b.st_size;
1346478Ssam again:
1356478Ssam 	while (read(log, (char *)&from, sizeof(from)) == sizeof(from)) {
1366478Ssam 		if (from.sin_family == 0) {
1376478Ssam 			printf("restarted: %.24s\n", ctime(&from.sin_time));
1386478Ssam 			continue;
1396478Ssam 		}
140*22597Skarels 		if (host >= 0) {
141*22597Skarels 			long addr = ntohs(from.sin_addr.s_addr);
142*22597Skarels 
143*22597Skarels 			if (IN_CLASSA(addr)) {
144*22597Skarels 				hostfrom = ((addr>>16) & 0xFF);
145*22597Skarels 				impfrom = addr & 0xFF;
146*22597Skarels 			} else if (IN_CLASSB(addr)) {
147*22597Skarels 				hostfrom = ((addr>>8) & 0xFF);
148*22597Skarels 				impfrom = addr & 0xFF;
149*22597Skarels 			} else {
150*22597Skarels 				hostfrom = ((addr>>4) & 0xF);
151*22597Skarels 				impfrom = addr & 0xF;
152*22597Skarels 			}
153*22597Skarels 		}
154*22597Skarels 		if (host >= 0 && hostfrom != host) {
1556478Ssam 			lseek(log, from.sin_cc, 1);
1566478Ssam 			continue;
1576478Ssam 		}
158*22597Skarels 		if (imp >= 0 && impfrom != imp) {
159*22597Skarels 			lseek(log, from.sin_cc, 1);
160*22597Skarels 			continue;
1616478Ssam 		}
1626478Ssam 		process(log, &from);
1636478Ssam 	}
1646478Ssam 	while (follow) {
1656478Ssam 		fflush(stdout);
1666478Ssam 		sleep(5);
1676478Ssam 		fstat(log, &b);
1686478Ssam 		if (b.st_size > size) {
1696478Ssam 			size = b.st_size;
1706478Ssam 			goto again;
1716478Ssam 		}
1726478Ssam 	}
1736478Ssam }
1746478Ssam 
1756478Ssam int	impdata(), impbadleader(), impdown(), impnoop();
1766478Ssam int	imprfnm(), impincomplete(), imphostdead(), imphostunreach();
1776478Ssam int	impbaddata(), impreset(), impretry(), impnotify(), imptrying();
1786478Ssam int	impready(), impundef();
1796478Ssam 
1806478Ssam struct	messages {
1816478Ssam 	u_char	m_type;		/* type of message */
1826478Ssam 	int	(*m_func)();	/* routine to process message */
1836478Ssam } mtypes[] = {
1846478Ssam 	{ IMPTYPE_DATA,		impdata },
1856478Ssam 	{ IMPTYPE_BADLEADER,	impbadleader },
1866478Ssam 	{ IMPTYPE_DOWN,		impdown },
1876478Ssam 	{ IMPTYPE_NOOP,		impnoop },
1886478Ssam 	{ IMPTYPE_RFNM,		imprfnm },
1896478Ssam 	{ IMPTYPE_INCOMPLETE,	impincomplete },
1906478Ssam 	{ IMPTYPE_HOSTDEAD,	imphostdead },
1916478Ssam 	{ IMPTYPE_HOSTUNREACH,	imphostunreach },
1926478Ssam 	{ IMPTYPE_BADDATA,	impbaddata },
1936478Ssam 	{ IMPTYPE_RESET,	impreset },
1946478Ssam 	{ IMPTYPE_RETRY,	impretry },
1956478Ssam 	{ IMPTYPE_NOTIFY,	impnotify },
1966478Ssam 	{ IMPTYPE_TRYING,	imptrying },
1976478Ssam 	{ IMPTYPE_READY,	impready },
1986478Ssam 	{ -1,			impundef }
1996478Ssam };
2006478Ssam 
2016478Ssam /*
2026478Ssam  * Print a packet.
2036478Ssam  */
2046478Ssam process(l, f)
2056478Ssam 	int l;
2066478Ssam 	struct sockstamp *f;
2076478Ssam {
2086478Ssam 	register struct messages *mp;
2096478Ssam 	struct imp_leader *ip;
2106478Ssam 
2116478Ssam 	if (read(l, (char *)buf, f->sin_cc) != f->sin_cc) {
2126478Ssam 		perror("read");
2136478Ssam 		return;
2146478Ssam 	}
2156478Ssam 	ip = (struct imp_leader *)buf;
2169195Ssam 	ip->il_imp = ntohs((u_short)ip->il_imp);
2176478Ssam 	for (mp = mtypes; mp->m_type != -1; mp++)
2186478Ssam 		if (mp->m_type == ip->il_mtype)
2196478Ssam 			break;
2206478Ssam 	if (mp->m_type == IMPTYPE_DATA) {
2216478Ssam 		if (link >= 0 && ip->il_link != link)
2226478Ssam 			return;
2236478Ssam 		if (!showdata)
2246478Ssam 			return;
2256478Ssam 	}
2266478Ssam 	if (packettype >= 0 && mp->m_type != packettype)
2276478Ssam 		return;
2286478Ssam 	printf("%.24s: ", ctime(&f->sin_time));
2296478Ssam 	(*mp->m_func)(ip, f->sin_cc);
2306478Ssam }
2316478Ssam 
2326478Ssam impdata(ip, cc)
2336478Ssam 	register struct imp_leader *ip;
2346478Ssam {
2359195Ssam 	printf("<%d/%d, DATA, link=", ip->il_host, ntohs((u_short)ip->il_imp));
2366478Ssam 	if (ip->il_link == IMPLINK_IP)
2376478Ssam 		printf("ip,");
2386478Ssam 	else
2396478Ssam 		printf("%d,", ip->il_link);
2409195Ssam 	printf(" len=%d bytes>\n", ntohs((u_short)ip->il_length) >> 3);
2416478Ssam 	if (showcontents) {
2426478Ssam 		register u_char *cp = ((u_char *)ip) + sizeof(*ip);
2436478Ssam 		register int i;
2446478Ssam 
2456478Ssam 		i = (ntohs(ip->il_length) >> 3) - sizeof(struct imp_leader);
2466478Ssam 		cc = min(i, cc);
2476478Ssam 		printf("data: (%d bytes)", cc);
2486478Ssam 		for (i = 0; i < cc; i++, cp++) {
2496478Ssam 			if (i % 25 == 0)
2506478Ssam 				printf("\n");
2516478Ssam 			printf("%02x ", *cp);
2526478Ssam 		}
2536478Ssam 		putchar('\n');
2546478Ssam 	}
2556478Ssam }
2566478Ssam 
2576478Ssam char *badleader[] = {
2586478Ssam 	"error flip-flop set",
2596478Ssam 	"message < 80 bits",
2606478Ssam 	"illegal type field",
2616478Ssam 	"opposite leader type"
2626478Ssam };
2636478Ssam 
2646478Ssam impbadleader(ip)
2656478Ssam 	register struct imp_leader *ip;
2666478Ssam {
2676478Ssam 	printf("bad leader: ");
2686478Ssam 	if (ip->il_subtype > IMPLEADER_OPPOSITE)
2696478Ssam 		printf("%x\n", ip->il_subtype);
2706478Ssam 	else
2716478Ssam 		printf("%s\n", badleader[ip->il_subtype]);
2726478Ssam }
2736478Ssam 
2746478Ssam char *down[] = {
2756478Ssam 	"in 30 secs",
2766478Ssam 	"for hardware pm",
2776478Ssam 	"for software reload",
2786478Ssam 	"for emergency restart"
2796478Ssam };
2806478Ssam 
2816478Ssam impdown(ip)
2826478Ssam 	register struct imp_leader *ip;
2836478Ssam {
2846478Ssam 	int tdown, tbackup;
2856478Ssam 
2866478Ssam 	printf("imp going down %s", down[ip->il_link & IMP_DMASK]);
2876478Ssam 	tdown = ((ip->il_link >> 2) & 0xf) * 5;
2886478Ssam 	if (ip->il_link & IMP_DMASK)
2896478Ssam 		printf(" in %d minutes", tdown);
2906478Ssam 	tbackup = ip->il_subtype * 5;
2916478Ssam 	printf(": back up ");
2926478Ssam 	if (tbackup)
2936478Ssam 		printf("%d minutes\n", tbackup);
2946478Ssam 	else
2956478Ssam 		printf("immediately\n");
2966478Ssam }
2976478Ssam 
2986478Ssam impnoop(ip)
2996478Ssam 	register struct imp_leader *ip;
3006478Ssam {
3019195Ssam 	printf("noop: host %d, imp %d\n", ip->il_host,
3029195Ssam 		ntohs((u_short)ip->il_imp));
3036478Ssam }
3046478Ssam 
3056478Ssam imprfnm(ip)
3066478Ssam 	register struct imp_leader *ip;
3076478Ssam {
3086478Ssam 	printf("rfnm: htype=%x, source=%d/%d, link=",
3096478Ssam 		ip->il_htype, ip->il_host, ip->il_imp);
3106478Ssam 	if (ip->il_link == IMPLINK_IP)
3116478Ssam 		printf("ip,");
3126478Ssam 	else
3136478Ssam 		printf("%x,", ip->il_link);
3146478Ssam 	printf(" subtype=%x\n", ip->il_subtype);
3156478Ssam }
3166478Ssam 
3176478Ssam char *hostdead[] = {
3189195Ssam 	"#0",
3196478Ssam 	"ready-line negated",
3206478Ssam 	"tardy receiving messages",
3216478Ssam 	"ncc doesn't know host",
3226478Ssam 	"imp software won't allow messages",
3236478Ssam 	"host down for scheduled pm",
3246478Ssam 	"host down for hardware work",
3256478Ssam 	"host down for software work",
3266478Ssam 	"host down for emergency restart",
3276478Ssam 	"host down because of power outage",
3286478Ssam 	"host stopped at a breakpoint",
3296478Ssam 	"host down due to hardware failure",
3306478Ssam 	"host not scheduled to be up",
3319195Ssam 	"#13",
3329195Ssam 	"#14",
3336478Ssam 	"host in the process of coming up"
3346478Ssam };
3356478Ssam 
3366478Ssam imphostdead(ip)
3376478Ssam 	register struct imp_leader *ip;
3386478Ssam {
3396478Ssam 	printf("host dead: ");
3406478Ssam 	if (ip->il_link & IMP_DMASK)
3416478Ssam 		printf("down %s, ", down[ip->il_link & IMP_DMASK]);
3426478Ssam 	if (ip->il_subtype <= IMPHOST_COMINGUP)
3436478Ssam 		printf("%s\n", hostdead[ip->il_subtype]);
3446478Ssam 	else
3456478Ssam 		printf("subtype=%x\n", ip->il_subtype);
3466478Ssam }
3476478Ssam 
3486478Ssam char *hostunreach[] = {
3496478Ssam 	"destination imp can't be reached",
3506478Ssam 	"destination host isn't up",
3516478Ssam 	"host doesn't support long leader",
3526478Ssam 	"communication is prohibited"
3536478Ssam };
3546478Ssam 
3556478Ssam imphostunreach(ip)
3566478Ssam 	register struct imp_leader *ip;
3576478Ssam {
3586478Ssam 	printf("host unreachable: ");
3596478Ssam 	if (ip->il_subtype <= IMPREACH_PROHIBITED)
3606478Ssam 		printf("%s\n", hostunreach[ip->il_subtype]);
3616478Ssam 	else
3626478Ssam 		printf("subtype=%x\n", ip->il_subtype);
3636478Ssam }
3646478Ssam 
3656478Ssam impbaddata(ip)
3666478Ssam 	register struct imp_leader *ip;
3676478Ssam {
3686478Ssam 	printf("error in data: htype=%x, source=%d/%d, link=",
3696478Ssam 		ip->il_htype, ip->il_host, ip->il_imp);
3706478Ssam 	if (ip->il_link == IMPLINK_IP)
3716478Ssam 		printf("ip, ");
3726478Ssam 	else
3736478Ssam 		printf("%x, ", ip->il_link);
3746478Ssam 	printf("subtype=%x\n", ip->il_subtype);
3756478Ssam }
3766478Ssam 
3776478Ssam char *incomplete[] = {
3786478Ssam 	"host didn't take data fast enough",
3796478Ssam 	"message was too long",
3806478Ssam 	"message transmission time > 15 seconds",
3816478Ssam 	"imp/circuit failure",
3826478Ssam 	"no resources within 15 seconds",
3836478Ssam 	"source imp i/o failure during receipt"
3846478Ssam };
3856478Ssam 
3866478Ssam impincomplete(ip)
3876478Ssam 	register struct imp_leader *ip;
3886478Ssam {
3896478Ssam 	printf("incomplete: htype=%x, source=%d/%d, link=",
3906478Ssam 		ip->il_htype, ip->il_host, ip->il_imp);
3916478Ssam 	if (ip->il_link == IMPLINK_IP)
3926478Ssam 		printf("ip,");
3936478Ssam 	else
3946478Ssam 		printf("%x,", ip->il_link);
3956478Ssam 	if (ip->il_subtype <= IMPCOMPLETE_IMPIO)
3966478Ssam 		printf(" %s\n", incomplete[ip->il_subtype]);
3976478Ssam 	else
3986478Ssam 		printf(" subtype=%x\n", ip->il_subtype);
3996478Ssam }
4006478Ssam 
4016478Ssam impreset(ip)
4026478Ssam 	register struct imp_leader *ip;
4036478Ssam {
4046478Ssam 	printf("reset complete\n");
4056478Ssam }
4066478Ssam 
4076478Ssam char *retry[] = {
4086478Ssam 	"imp buffer wasn't available",
4096478Ssam 	"connection block unavailable"
4106478Ssam };
4116478Ssam 
4126478Ssam impretry(ip)
4136478Ssam 	register struct imp_leader *ip;
4146478Ssam {
4156478Ssam 	printf("refused, try again: ");
4166478Ssam 	if (ip->il_subtype <= IMPRETRY_BLOCK)
4176478Ssam 		printf("%s\n", retry[ip->il_subtype]);
4186478Ssam 	else
4196478Ssam 		printf("subtype=%x\n", ip->il_subtype);
4206478Ssam }
4216478Ssam 
4226478Ssam char *notify[] = {
4239195Ssam 	"#0",
4249195Ssam 	"#1",
4256478Ssam 	"connection not available",
4266478Ssam 	"reassembly space not available at destination",
4276478Ssam 	"message number not available",
4286478Ssam 	"transaction block for message not available"
4296478Ssam };
4306478Ssam 
4316478Ssam impnotify(ip)
4326478Ssam 	register struct imp_leader *ip;
4336478Ssam {
4346478Ssam 	printf("refused, will notify: ");
4356478Ssam 	if (ip->il_subtype <= 5)
4366478Ssam 		printf("%s\n", notify[ip->il_subtype]);
4376478Ssam 	else
4386478Ssam 		printf("subtype=%x\n", ip->il_subtype);
4396478Ssam }
4406478Ssam 
4416478Ssam imptrying(ip)
4426478Ssam 	register struct imp_leader *ip;
4436478Ssam {
4446478Ssam 	printf("refused, still trying\n");
4456478Ssam }
4466478Ssam 
4476478Ssam impready(ip)
4486478Ssam 	register struct imp_leader *ip;
4496478Ssam {
4506478Ssam 	printf("ready\n");
4516478Ssam }
4526478Ssam 
4536478Ssam impundef(ip)
4546478Ssam 	register struct imp_leader *ip;
4556478Ssam {
4566478Ssam 	printf("<fmt=%x, net=%x, flags=%x, mtype=", ip->il_format,
4576478Ssam 		ip->il_network, ip->il_flags);
4586478Ssam 	printf("%x, htype=%x, host=%x, imp=%x, link=", ip->il_mtype,
4596478Ssam 		ip->il_htype, ip->il_host, ip->il_imp);
4606478Ssam 	if (ip->il_link == IMPLINK_IP)
4616478Ssam 		printf("ip,");
4626478Ssam 	else
4636478Ssam 		printf("%x,", ip->il_link);
4646478Ssam 	printf(" subtype=%x>\n", ip->il_subtype);
4656478Ssam }
466