xref: /csrg-svn/old/implog/implog.c (revision 13600)
19197Ssam #ifndef lint
2*13600Ssam static char sccsid[] = "@(#)implog.c	4.4 (Berkeley) 07/01/83";
39197Ssam #endif
46478Ssam 
56478Ssam #include <stdio.h>
66478Ssam #include <signal.h>
76478Ssam #include <sgtty.h>
89195Ssam 
9*13600Ssam #include <sys/time.h>
106478Ssam #include <sys/types.h>
116478Ssam #include <sys/stat.h>
126478Ssam #include <sys/socket.h>
139195Ssam 
149195Ssam #include <netinet/in.h>
156478Ssam #define	IMPLEADERS
169195Ssam #include <netimp/if_imp.h>
176478Ssam 
186478Ssam #define	min(a, b)	((a) < (b) ? (a) : (b))
196478Ssam 
206478Ssam u_char	buf[1024];
216478Ssam int	showdata = 1;
226478Ssam int	showcontents = 0;
236478Ssam int	follow = 0;
246478Ssam int	link = -1;
256478Ssam int	host = -1;
266478Ssam int	imp = -1;
276478Ssam int	packettype = -1;
286478Ssam extern	int errno;
296478Ssam int	log;
306478Ssam char	*logfile = "/usr/adm/implog";
316478Ssam 
326478Ssam /*
336478Ssam  * Socket address, internet style, with
346478Ssam  * unused space taken by timestamp and packet
356478Ssam  * size.
366478Ssam  */
376478Ssam struct sockstamp {
386478Ssam 	short	sin_family;
396478Ssam 	u_short	sin_port;
406478Ssam 	struct	in_addr sin_addr;
416478Ssam 	time_t	sin_time;
426478Ssam 	int	sin_cc;
436478Ssam };
446478Ssam struct	sockstamp from;
456478Ssam 
466478Ssam main(argc, argv)
476478Ssam 	char *argv[];
486478Ssam {
496478Ssam 	struct stat b;
506478Ssam 	int size;
516478Ssam 	char *cp;
526478Ssam 
536478Ssam 	argc--, argv++;
546478Ssam 	while (argc > 0 && argv[0][0] == '-') {
556478Ssam 		if (strcmp(*argv, "-D") == 0) {
566478Ssam 			showdata = 0;
576478Ssam 			argv++, argc--;
586478Ssam 			continue;
596478Ssam 		}
606478Ssam 		if (strcmp(*argv, "-f") == 0) {
616478Ssam 			follow++;
626478Ssam 			argv++, argc--;
636478Ssam 			continue;
646478Ssam 		}
656478Ssam 		if (strcmp(*argv, "-c") == 0) {
666478Ssam 			showcontents++;
676478Ssam 			argv++, argc--;
686478Ssam 			continue;
696478Ssam 		}
706478Ssam 		if (strcmp(*argv, "-l") == 0) {
716478Ssam 			argc--, argv++;
726478Ssam 			if (argc > 0) {
736478Ssam 				link = atoi(*argv);
746478Ssam 				argc--, argv++;
756478Ssam 			} else
766478Ssam 				link = IMPLINK_IP;
776478Ssam 			continue;
786478Ssam 		}
796478Ssam 		if (strcmp(*argv, "-h") == 0) {
806478Ssam 			argc--, argv++;
816478Ssam 			if (argc < 1) {
826478Ssam 				printf("-h: missing host #\n");
836478Ssam 				exit(2);
846478Ssam 			}
856478Ssam 			host = atoi(*argv);
866478Ssam 			argv++, argc--;
876478Ssam 			continue;
886478Ssam 		}
896478Ssam 		if (strcmp(*argv, "-i") == 0) {
906478Ssam 			argc--, argv++;
916478Ssam 			if (argc < 1) {
926478Ssam 				printf("-i: missing imp #\n");
936478Ssam 				exit(2);
946478Ssam 			}
956478Ssam 			imp = atoi(*argv);
966478Ssam 			argv++, argc--;
976478Ssam 			continue;
986478Ssam 		}
996478Ssam 		if (strcmp(*argv, "-t") == 0) {
1006478Ssam 			argc--, argv++;;
1016478Ssam 			if (argc < 1) {
1026478Ssam 				printf("-t: missing packet type\n");
1036478Ssam 				exit(2);
1046478Ssam 			}
1056478Ssam 			packettype = atoi(*argv);
1066478Ssam 			argv++, argc--;;
1076478Ssam 			continue;
1086478Ssam 		}
1099195Ssam 		printf("usage: implog [ -D ] [ -c ] [ -f ] [-h #] [-i #] [ -t # ] [-l [#]] [logfile]\n");
1106478Ssam 		exit(2);
1116478Ssam 	}
1126478Ssam 	if (argc > 0)
1136478Ssam 		logfile = argv[0];
1146478Ssam 	log = open(logfile, 0);
1156478Ssam 	if (log < 0) {
1166478Ssam 		perror(logfile);
1176478Ssam 		exit(1);
1186478Ssam 	}
1196478Ssam 	fstat(log, &b);
1206478Ssam 	size = b.st_size;
1216478Ssam again:
1226478Ssam 	while (read(log, (char *)&from, sizeof(from)) == sizeof(from)) {
1236478Ssam 		if (from.sin_family == 0) {
1246478Ssam 			printf("restarted: %.24s\n", ctime(&from.sin_time));
1256478Ssam 			continue;
1266478Ssam 		}
1276478Ssam 		if (host >= 0 && from.sin_addr.s_host != host) {
1286478Ssam 			lseek(log, from.sin_cc, 1);
1296478Ssam 			continue;
1306478Ssam 		}
1316478Ssam 		if (imp >= 0) {
1326478Ssam 			from.sin_addr.s_imp = ntohs(from.sin_addr.s_imp);
1336478Ssam 			if (from.sin_addr.s_imp != imp) {
1346478Ssam 				lseek(log, from.sin_cc, 1);
1356478Ssam 				continue;
1366478Ssam 			}
1376478Ssam 		}
1386478Ssam 		process(log, &from);
1396478Ssam 	}
1406478Ssam 	while (follow) {
1416478Ssam 		fflush(stdout);
1426478Ssam 		sleep(5);
1436478Ssam 		fstat(log, &b);
1446478Ssam 		if (b.st_size > size) {
1456478Ssam 			size = b.st_size;
1466478Ssam 			goto again;
1476478Ssam 		}
1486478Ssam 	}
1496478Ssam }
1506478Ssam 
1516478Ssam int	impdata(), impbadleader(), impdown(), impnoop();
1526478Ssam int	imprfnm(), impincomplete(), imphostdead(), imphostunreach();
1536478Ssam int	impbaddata(), impreset(), impretry(), impnotify(), imptrying();
1546478Ssam int	impready(), impundef();
1556478Ssam 
1566478Ssam struct	messages {
1576478Ssam 	u_char	m_type;		/* type of message */
1586478Ssam 	int	(*m_func)();	/* routine to process message */
1596478Ssam } mtypes[] = {
1606478Ssam 	{ IMPTYPE_DATA,		impdata },
1616478Ssam 	{ IMPTYPE_BADLEADER,	impbadleader },
1626478Ssam 	{ IMPTYPE_DOWN,		impdown },
1636478Ssam 	{ IMPTYPE_NOOP,		impnoop },
1646478Ssam 	{ IMPTYPE_RFNM,		imprfnm },
1656478Ssam 	{ IMPTYPE_INCOMPLETE,	impincomplete },
1666478Ssam 	{ IMPTYPE_HOSTDEAD,	imphostdead },
1676478Ssam 	{ IMPTYPE_HOSTUNREACH,	imphostunreach },
1686478Ssam 	{ IMPTYPE_BADDATA,	impbaddata },
1696478Ssam 	{ IMPTYPE_RESET,	impreset },
1706478Ssam 	{ IMPTYPE_RETRY,	impretry },
1716478Ssam 	{ IMPTYPE_NOTIFY,	impnotify },
1726478Ssam 	{ IMPTYPE_TRYING,	imptrying },
1736478Ssam 	{ IMPTYPE_READY,	impready },
1746478Ssam 	{ -1,			impundef }
1756478Ssam };
1766478Ssam 
1776478Ssam /*
1786478Ssam  * Print a packet.
1796478Ssam  */
1806478Ssam process(l, f)
1816478Ssam 	int l;
1826478Ssam 	struct sockstamp *f;
1836478Ssam {
1846478Ssam 	register struct messages *mp;
1856478Ssam 	struct imp_leader *ip;
1866478Ssam 
1876478Ssam 	if (read(l, (char *)buf, f->sin_cc) != f->sin_cc) {
1886478Ssam 		perror("read");
1896478Ssam 		return;
1906478Ssam 	}
1916478Ssam 	ip = (struct imp_leader *)buf;
1929195Ssam 	ip->il_imp = ntohs((u_short)ip->il_imp);
1936478Ssam 	for (mp = mtypes; mp->m_type != -1; mp++)
1946478Ssam 		if (mp->m_type == ip->il_mtype)
1956478Ssam 			break;
1966478Ssam 	if (mp->m_type == IMPTYPE_DATA) {
1976478Ssam 		if (link >= 0 && ip->il_link != link)
1986478Ssam 			return;
1996478Ssam 		if (!showdata)
2006478Ssam 			return;
2016478Ssam 	}
2026478Ssam 	if (packettype >= 0 && mp->m_type != packettype)
2036478Ssam 		return;
2046478Ssam 	printf("%.24s: ", ctime(&f->sin_time));
2056478Ssam 	(*mp->m_func)(ip, f->sin_cc);
2066478Ssam }
2076478Ssam 
2086478Ssam impdata(ip, cc)
2096478Ssam 	register struct imp_leader *ip;
2106478Ssam {
2119195Ssam 	printf("<%d/%d, DATA, link=", ip->il_host, ntohs((u_short)ip->il_imp));
2126478Ssam 	if (ip->il_link == IMPLINK_IP)
2136478Ssam 		printf("ip,");
2146478Ssam 	else
2156478Ssam 		printf("%d,", ip->il_link);
2169195Ssam 	printf(" len=%d bytes>\n", ntohs((u_short)ip->il_length) >> 3);
2176478Ssam 	if (showcontents) {
2186478Ssam 		register u_char *cp = ((u_char *)ip) + sizeof(*ip);
2196478Ssam 		register int i;
2206478Ssam 
2216478Ssam 		i = (ntohs(ip->il_length) >> 3) - sizeof(struct imp_leader);
2226478Ssam 		cc = min(i, cc);
2236478Ssam 		printf("data: (%d bytes)", cc);
2246478Ssam 		for (i = 0; i < cc; i++, cp++) {
2256478Ssam 			if (i % 25 == 0)
2266478Ssam 				printf("\n");
2276478Ssam 			printf("%02x ", *cp);
2286478Ssam 		}
2296478Ssam 		putchar('\n');
2306478Ssam 	}
2316478Ssam }
2326478Ssam 
2336478Ssam char *badleader[] = {
2346478Ssam 	"error flip-flop set",
2356478Ssam 	"message < 80 bits",
2366478Ssam 	"illegal type field",
2376478Ssam 	"opposite leader type"
2386478Ssam };
2396478Ssam 
2406478Ssam impbadleader(ip)
2416478Ssam 	register struct imp_leader *ip;
2426478Ssam {
2436478Ssam 	printf("bad leader: ");
2446478Ssam 	if (ip->il_subtype > IMPLEADER_OPPOSITE)
2456478Ssam 		printf("%x\n", ip->il_subtype);
2466478Ssam 	else
2476478Ssam 		printf("%s\n", badleader[ip->il_subtype]);
2486478Ssam }
2496478Ssam 
2506478Ssam char *down[] = {
2516478Ssam 	"in 30 secs",
2526478Ssam 	"for hardware pm",
2536478Ssam 	"for software reload",
2546478Ssam 	"for emergency restart"
2556478Ssam };
2566478Ssam 
2576478Ssam impdown(ip)
2586478Ssam 	register struct imp_leader *ip;
2596478Ssam {
2606478Ssam 	int tdown, tbackup;
2616478Ssam 
2626478Ssam 	printf("imp going down %s", down[ip->il_link & IMP_DMASK]);
2636478Ssam 	tdown = ((ip->il_link >> 2) & 0xf) * 5;
2646478Ssam 	if (ip->il_link & IMP_DMASK)
2656478Ssam 		printf(" in %d minutes", tdown);
2666478Ssam 	tbackup = ip->il_subtype * 5;
2676478Ssam 	printf(": back up ");
2686478Ssam 	if (tbackup)
2696478Ssam 		printf("%d minutes\n", tbackup);
2706478Ssam 	else
2716478Ssam 		printf("immediately\n");
2726478Ssam }
2736478Ssam 
2746478Ssam impnoop(ip)
2756478Ssam 	register struct imp_leader *ip;
2766478Ssam {
2779195Ssam 	printf("noop: host %d, imp %d\n", ip->il_host,
2789195Ssam 		ntohs((u_short)ip->il_imp));
2796478Ssam }
2806478Ssam 
2816478Ssam imprfnm(ip)
2826478Ssam 	register struct imp_leader *ip;
2836478Ssam {
2846478Ssam 	printf("rfnm: htype=%x, source=%d/%d, link=",
2856478Ssam 		ip->il_htype, ip->il_host, ip->il_imp);
2866478Ssam 	if (ip->il_link == IMPLINK_IP)
2876478Ssam 		printf("ip,");
2886478Ssam 	else
2896478Ssam 		printf("%x,", ip->il_link);
2906478Ssam 	printf(" subtype=%x\n", ip->il_subtype);
2916478Ssam }
2926478Ssam 
2936478Ssam char *hostdead[] = {
2949195Ssam 	"#0",
2956478Ssam 	"ready-line negated",
2966478Ssam 	"tardy receiving messages",
2976478Ssam 	"ncc doesn't know host",
2986478Ssam 	"imp software won't allow messages",
2996478Ssam 	"host down for scheduled pm",
3006478Ssam 	"host down for hardware work",
3016478Ssam 	"host down for software work",
3026478Ssam 	"host down for emergency restart",
3036478Ssam 	"host down because of power outage",
3046478Ssam 	"host stopped at a breakpoint",
3056478Ssam 	"host down due to hardware failure",
3066478Ssam 	"host not scheduled to be up",
3079195Ssam 	"#13",
3089195Ssam 	"#14",
3096478Ssam 	"host in the process of coming up"
3106478Ssam };
3116478Ssam 
3126478Ssam imphostdead(ip)
3136478Ssam 	register struct imp_leader *ip;
3146478Ssam {
3156478Ssam 	printf("host dead: ");
3166478Ssam 	if (ip->il_link & IMP_DMASK)
3176478Ssam 		printf("down %s, ", down[ip->il_link & IMP_DMASK]);
3186478Ssam 	if (ip->il_subtype <= IMPHOST_COMINGUP)
3196478Ssam 		printf("%s\n", hostdead[ip->il_subtype]);
3206478Ssam 	else
3216478Ssam 		printf("subtype=%x\n", ip->il_subtype);
3226478Ssam }
3236478Ssam 
3246478Ssam char *hostunreach[] = {
3256478Ssam 	"destination imp can't be reached",
3266478Ssam 	"destination host isn't up",
3276478Ssam 	"host doesn't support long leader",
3286478Ssam 	"communication is prohibited"
3296478Ssam };
3306478Ssam 
3316478Ssam imphostunreach(ip)
3326478Ssam 	register struct imp_leader *ip;
3336478Ssam {
3346478Ssam 	printf("host unreachable: ");
3356478Ssam 	if (ip->il_subtype <= IMPREACH_PROHIBITED)
3366478Ssam 		printf("%s\n", hostunreach[ip->il_subtype]);
3376478Ssam 	else
3386478Ssam 		printf("subtype=%x\n", ip->il_subtype);
3396478Ssam }
3406478Ssam 
3416478Ssam impbaddata(ip)
3426478Ssam 	register struct imp_leader *ip;
3436478Ssam {
3446478Ssam 	printf("error in data: htype=%x, source=%d/%d, link=",
3456478Ssam 		ip->il_htype, ip->il_host, ip->il_imp);
3466478Ssam 	if (ip->il_link == IMPLINK_IP)
3476478Ssam 		printf("ip, ");
3486478Ssam 	else
3496478Ssam 		printf("%x, ", ip->il_link);
3506478Ssam 	printf("subtype=%x\n", ip->il_subtype);
3516478Ssam }
3526478Ssam 
3536478Ssam char *incomplete[] = {
3546478Ssam 	"host didn't take data fast enough",
3556478Ssam 	"message was too long",
3566478Ssam 	"message transmission time > 15 seconds",
3576478Ssam 	"imp/circuit failure",
3586478Ssam 	"no resources within 15 seconds",
3596478Ssam 	"source imp i/o failure during receipt"
3606478Ssam };
3616478Ssam 
3626478Ssam impincomplete(ip)
3636478Ssam 	register struct imp_leader *ip;
3646478Ssam {
3656478Ssam 	printf("incomplete: htype=%x, source=%d/%d, link=",
3666478Ssam 		ip->il_htype, ip->il_host, ip->il_imp);
3676478Ssam 	if (ip->il_link == IMPLINK_IP)
3686478Ssam 		printf("ip,");
3696478Ssam 	else
3706478Ssam 		printf("%x,", ip->il_link);
3716478Ssam 	if (ip->il_subtype <= IMPCOMPLETE_IMPIO)
3726478Ssam 		printf(" %s\n", incomplete[ip->il_subtype]);
3736478Ssam 	else
3746478Ssam 		printf(" subtype=%x\n", ip->il_subtype);
3756478Ssam }
3766478Ssam 
3776478Ssam impreset(ip)
3786478Ssam 	register struct imp_leader *ip;
3796478Ssam {
3806478Ssam 	printf("reset complete\n");
3816478Ssam }
3826478Ssam 
3836478Ssam char *retry[] = {
3846478Ssam 	"imp buffer wasn't available",
3856478Ssam 	"connection block unavailable"
3866478Ssam };
3876478Ssam 
3886478Ssam impretry(ip)
3896478Ssam 	register struct imp_leader *ip;
3906478Ssam {
3916478Ssam 	printf("refused, try again: ");
3926478Ssam 	if (ip->il_subtype <= IMPRETRY_BLOCK)
3936478Ssam 		printf("%s\n", retry[ip->il_subtype]);
3946478Ssam 	else
3956478Ssam 		printf("subtype=%x\n", ip->il_subtype);
3966478Ssam }
3976478Ssam 
3986478Ssam char *notify[] = {
3999195Ssam 	"#0",
4009195Ssam 	"#1",
4016478Ssam 	"connection not available",
4026478Ssam 	"reassembly space not available at destination",
4036478Ssam 	"message number not available",
4046478Ssam 	"transaction block for message not available"
4056478Ssam };
4066478Ssam 
4076478Ssam impnotify(ip)
4086478Ssam 	register struct imp_leader *ip;
4096478Ssam {
4106478Ssam 	printf("refused, will notify: ");
4116478Ssam 	if (ip->il_subtype <= 5)
4126478Ssam 		printf("%s\n", notify[ip->il_subtype]);
4136478Ssam 	else
4146478Ssam 		printf("subtype=%x\n", ip->il_subtype);
4156478Ssam }
4166478Ssam 
4176478Ssam imptrying(ip)
4186478Ssam 	register struct imp_leader *ip;
4196478Ssam {
4206478Ssam 	printf("refused, still trying\n");
4216478Ssam }
4226478Ssam 
4236478Ssam impready(ip)
4246478Ssam 	register struct imp_leader *ip;
4256478Ssam {
4266478Ssam 	printf("ready\n");
4276478Ssam }
4286478Ssam 
4296478Ssam impundef(ip)
4306478Ssam 	register struct imp_leader *ip;
4316478Ssam {
4326478Ssam 	printf("<fmt=%x, net=%x, flags=%x, mtype=", ip->il_format,
4336478Ssam 		ip->il_network, ip->il_flags);
4346478Ssam 	printf("%x, htype=%x, host=%x, imp=%x, link=", ip->il_mtype,
4356478Ssam 		ip->il_htype, ip->il_host, ip->il_imp);
4366478Ssam 	if (ip->il_link == IMPLINK_IP)
4376478Ssam 		printf("ip,");
4386478Ssam 	else
4396478Ssam 		printf("%x,", ip->il_link);
4406478Ssam 	printf(" subtype=%x>\n", ip->il_subtype);
4416478Ssam }
442