xref: /csrg-svn/old/implog/implog.c (revision 28904)
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*28904Skarels static char sccsid[] = "@(#)implog.c	5.5 (Berkeley) 05/30/86";
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;
3527727Skarels int	rawheader = 0;
366478Ssam int	follow = 0;
376478Ssam int	link = -1;
386478Ssam int	host = -1;
396478Ssam int	imp = -1;
406478Ssam int	packettype = -1;
416478Ssam extern	int errno;
426478Ssam int	log;
436478Ssam char	*logfile = "/usr/adm/implog";
446478Ssam 
456478Ssam /*
466478Ssam  * Socket address, internet style, with
476478Ssam  * unused space taken by timestamp and packet
486478Ssam  * size.
496478Ssam  */
506478Ssam struct sockstamp {
516478Ssam 	short	sin_family;
526478Ssam 	u_short	sin_port;
536478Ssam 	struct	in_addr sin_addr;
546478Ssam 	time_t	sin_time;
556478Ssam 	int	sin_cc;
566478Ssam };
576478Ssam struct	sockstamp from;
586478Ssam 
596478Ssam main(argc, argv)
606478Ssam 	char *argv[];
616478Ssam {
626478Ssam 	struct stat b;
636478Ssam 	int size;
646478Ssam 	char *cp;
6522597Skarels 	int hostfrom, impfrom;
666478Ssam 
676478Ssam 	argc--, argv++;
686478Ssam 	while (argc > 0 && argv[0][0] == '-') {
696478Ssam 		if (strcmp(*argv, "-D") == 0) {
706478Ssam 			showdata = 0;
716478Ssam 			argv++, argc--;
726478Ssam 			continue;
736478Ssam 		}
746478Ssam 		if (strcmp(*argv, "-f") == 0) {
756478Ssam 			follow++;
766478Ssam 			argv++, argc--;
776478Ssam 			continue;
786478Ssam 		}
796478Ssam 		if (strcmp(*argv, "-c") == 0) {
806478Ssam 			showcontents++;
816478Ssam 			argv++, argc--;
826478Ssam 			continue;
836478Ssam 		}
8427727Skarels 		if (strcmp(*argv, "-r") == 0) {
8527727Skarels 			rawheader++;
8627727Skarels 			argv++, argc--;
8727727Skarels 			continue;
8827727Skarels 		}
896478Ssam 		if (strcmp(*argv, "-l") == 0) {
906478Ssam 			argc--, argv++;
916478Ssam 			if (argc > 0) {
926478Ssam 				link = atoi(*argv);
936478Ssam 				argc--, argv++;
946478Ssam 			} else
956478Ssam 				link = IMPLINK_IP;
966478Ssam 			continue;
976478Ssam 		}
986478Ssam 		if (strcmp(*argv, "-h") == 0) {
996478Ssam 			argc--, argv++;
1006478Ssam 			if (argc < 1) {
1016478Ssam 				printf("-h: missing host #\n");
1026478Ssam 				exit(2);
1036478Ssam 			}
1046478Ssam 			host = atoi(*argv);
1056478Ssam 			argv++, argc--;
1066478Ssam 			continue;
1076478Ssam 		}
1086478Ssam 		if (strcmp(*argv, "-i") == 0) {
1096478Ssam 			argc--, argv++;
1106478Ssam 			if (argc < 1) {
1116478Ssam 				printf("-i: missing imp #\n");
1126478Ssam 				exit(2);
1136478Ssam 			}
1146478Ssam 			imp = atoi(*argv);
1156478Ssam 			argv++, argc--;
1166478Ssam 			continue;
1176478Ssam 		}
1186478Ssam 		if (strcmp(*argv, "-t") == 0) {
1196478Ssam 			argc--, argv++;;
1206478Ssam 			if (argc < 1) {
1216478Ssam 				printf("-t: missing packet type\n");
1226478Ssam 				exit(2);
1236478Ssam 			}
1246478Ssam 			packettype = atoi(*argv);
1256478Ssam 			argv++, argc--;;
1266478Ssam 			continue;
1276478Ssam 		}
12827727Skarels 		printf("usage: implog [ -D ] [ -c ] [ -f ] [ -r ] [-h #] [-i #] [ -t # ] [-l [#]] [logfile]\n");
1296478Ssam 		exit(2);
1306478Ssam 	}
1316478Ssam 	if (argc > 0)
1326478Ssam 		logfile = argv[0];
1336478Ssam 	log = open(logfile, 0);
1346478Ssam 	if (log < 0) {
1356478Ssam 		perror(logfile);
1366478Ssam 		exit(1);
1376478Ssam 	}
1386478Ssam 	fstat(log, &b);
1396478Ssam 	size = b.st_size;
1406478Ssam again:
1416478Ssam 	while (read(log, (char *)&from, sizeof(from)) == sizeof(from)) {
1426478Ssam 		if (from.sin_family == 0) {
1436478Ssam 			printf("restarted: %.24s\n", ctime(&from.sin_time));
1446478Ssam 			continue;
1456478Ssam 		}
14622597Skarels 		if (host >= 0) {
14722597Skarels 			long addr = ntohs(from.sin_addr.s_addr);
14822597Skarels 
14922597Skarels 			if (IN_CLASSA(addr)) {
15022597Skarels 				hostfrom = ((addr>>16) & 0xFF);
15122597Skarels 				impfrom = addr & 0xFF;
15222597Skarels 			} else if (IN_CLASSB(addr)) {
15322597Skarels 				hostfrom = ((addr>>8) & 0xFF);
15422597Skarels 				impfrom = addr & 0xFF;
15522597Skarels 			} else {
15622597Skarels 				hostfrom = ((addr>>4) & 0xF);
15722597Skarels 				impfrom = addr & 0xF;
15822597Skarels 			}
15922597Skarels 		}
16022597Skarels 		if (host >= 0 && hostfrom != host) {
1616478Ssam 			lseek(log, from.sin_cc, 1);
1626478Ssam 			continue;
1636478Ssam 		}
16422597Skarels 		if (imp >= 0 && impfrom != imp) {
16522597Skarels 			lseek(log, from.sin_cc, 1);
16622597Skarels 			continue;
1676478Ssam 		}
1686478Ssam 		process(log, &from);
1696478Ssam 	}
1706478Ssam 	while (follow) {
1716478Ssam 		fflush(stdout);
1726478Ssam 		sleep(5);
1736478Ssam 		fstat(log, &b);
1746478Ssam 		if (b.st_size > size) {
1756478Ssam 			size = b.st_size;
1766478Ssam 			goto again;
1776478Ssam 		}
1786478Ssam 	}
1796478Ssam }
1806478Ssam 
1816478Ssam int	impdata(), impbadleader(), impdown(), impnoop();
1826478Ssam int	imprfnm(), impincomplete(), imphostdead(), imphostunreach();
1836478Ssam int	impbaddata(), impreset(), impretry(), impnotify(), imptrying();
1846478Ssam int	impready(), impundef();
1856478Ssam 
1866478Ssam struct	messages {
1876478Ssam 	u_char	m_type;		/* type of message */
1886478Ssam 	int	(*m_func)();	/* routine to process message */
1896478Ssam } mtypes[] = {
1906478Ssam 	{ IMPTYPE_DATA,		impdata },
1916478Ssam 	{ IMPTYPE_BADLEADER,	impbadleader },
1926478Ssam 	{ IMPTYPE_DOWN,		impdown },
1936478Ssam 	{ IMPTYPE_NOOP,		impnoop },
1946478Ssam 	{ IMPTYPE_RFNM,		imprfnm },
1956478Ssam 	{ IMPTYPE_INCOMPLETE,	impincomplete },
1966478Ssam 	{ IMPTYPE_HOSTDEAD,	imphostdead },
1976478Ssam 	{ IMPTYPE_HOSTUNREACH,	imphostunreach },
1986478Ssam 	{ IMPTYPE_BADDATA,	impbaddata },
1996478Ssam 	{ IMPTYPE_RESET,	impreset },
2006478Ssam 	{ IMPTYPE_RETRY,	impretry },
2016478Ssam 	{ IMPTYPE_NOTIFY,	impnotify },
2026478Ssam 	{ IMPTYPE_TRYING,	imptrying },
2036478Ssam 	{ IMPTYPE_READY,	impready },
2046478Ssam 	{ -1,			impundef }
2056478Ssam };
2066478Ssam 
2076478Ssam /*
2086478Ssam  * Print a packet.
2096478Ssam  */
2106478Ssam process(l, f)
2116478Ssam 	int l;
2126478Ssam 	struct sockstamp *f;
2136478Ssam {
2146478Ssam 	register struct messages *mp;
2156478Ssam 	struct imp_leader *ip;
21627727Skarels 	int (*fn)();
2176478Ssam 
2186478Ssam 	if (read(l, (char *)buf, f->sin_cc) != f->sin_cc) {
2196478Ssam 		perror("read");
2206478Ssam 		return;
2216478Ssam 	}
2226478Ssam 	ip = (struct imp_leader *)buf;
223*28904Skarels 	ip->il_imp = ntohs(ip->il_imp);
22427727Skarels 	if (ip->il_format != IMP_NFF)
22527727Skarels 		fn = impundef;
22627727Skarels 	else {
22727727Skarels 		for (mp = mtypes; mp->m_type != -1; mp++)
22827727Skarels 			if (mp->m_type == ip->il_mtype)
22927727Skarels 				break;
23027727Skarels 		fn = mp->m_func;
23127727Skarels 	}
23227727Skarels 	if (ip->il_mtype == IMPTYPE_DATA) {
2336478Ssam 		if (link >= 0 && ip->il_link != link)
2346478Ssam 			return;
2356478Ssam 		if (!showdata)
2366478Ssam 			return;
2376478Ssam 	}
23827727Skarels 	if (packettype >= 0 && ip->il_mtype != packettype)
2396478Ssam 		return;
2406478Ssam 	printf("%.24s: ", ctime(&f->sin_time));
241*28904Skarels 	if (f->sin_cc < sizeof(struct control_leader))
242*28904Skarels 		printf("(truncated header, %d bytes): ", f->sin_cc);
24327727Skarels 	(*fn)(ip, f->sin_cc);
244*28904Skarels 	if (rawheader && fn != impundef) {
245*28904Skarels 		putchar('\t');
24627727Skarels 		impundef(ip, f->sin_cc);
247*28904Skarels 	}
2486478Ssam }
2496478Ssam 
2506478Ssam impdata(ip, cc)
2516478Ssam 	register struct imp_leader *ip;
2526478Ssam {
25327727Skarels 	printf("<DATA, source=%d/%d, link=", ip->il_host, (u_short)ip->il_imp);
2546478Ssam 	if (ip->il_link == IMPLINK_IP)
2556478Ssam 		printf("ip,");
2566478Ssam 	else
2576478Ssam 		printf("%d,", ip->il_link);
2589195Ssam 	printf(" len=%d bytes>\n", ntohs((u_short)ip->il_length) >> 3);
2596478Ssam 	if (showcontents) {
2606478Ssam 		register u_char *cp = ((u_char *)ip) + sizeof(*ip);
2616478Ssam 		register int i;
2626478Ssam 
2636478Ssam 		i = (ntohs(ip->il_length) >> 3) - sizeof(struct imp_leader);
2646478Ssam 		cc = min(i, cc);
2656478Ssam 		printf("data: (%d bytes)", cc);
2666478Ssam 		for (i = 0; i < cc; i++, cp++) {
2676478Ssam 			if (i % 25 == 0)
2686478Ssam 				printf("\n");
2696478Ssam 			printf("%02x ", *cp);
2706478Ssam 		}
2716478Ssam 		putchar('\n');
2726478Ssam 	}
2736478Ssam }
2746478Ssam 
2756478Ssam char *badleader[] = {
2766478Ssam 	"error flip-flop set",
2776478Ssam 	"message < 80 bits",
2786478Ssam 	"illegal type field",
2796478Ssam 	"opposite leader type"
2806478Ssam };
2816478Ssam 
2826478Ssam impbadleader(ip)
2836478Ssam 	register struct imp_leader *ip;
2846478Ssam {
2856478Ssam 	printf("bad leader: ");
2866478Ssam 	if (ip->il_subtype > IMPLEADER_OPPOSITE)
2876478Ssam 		printf("%x\n", ip->il_subtype);
2886478Ssam 	else
2896478Ssam 		printf("%s\n", badleader[ip->il_subtype]);
2906478Ssam }
2916478Ssam 
2926478Ssam char *down[] = {
2936478Ssam 	"in 30 secs",
2946478Ssam 	"for hardware pm",
2956478Ssam 	"for software reload",
2966478Ssam 	"for emergency restart"
2976478Ssam };
2986478Ssam 
2996478Ssam impdown(ip)
3006478Ssam 	register struct imp_leader *ip;
3016478Ssam {
3026478Ssam 	int tdown, tbackup;
3036478Ssam 
3046478Ssam 	printf("imp going down %s", down[ip->il_link & IMP_DMASK]);
3056478Ssam 	tdown = ((ip->il_link >> 2) & 0xf) * 5;
3066478Ssam 	if (ip->il_link & IMP_DMASK)
3076478Ssam 		printf(" in %d minutes", tdown);
3086478Ssam 	tbackup = ip->il_subtype * 5;
3096478Ssam 	printf(": back up ");
3106478Ssam 	if (tbackup)
3116478Ssam 		printf("%d minutes\n", tbackup);
3126478Ssam 	else
3136478Ssam 		printf("immediately\n");
3146478Ssam }
3156478Ssam 
3166478Ssam impnoop(ip)
3176478Ssam 	register struct imp_leader *ip;
3186478Ssam {
3199195Ssam 	printf("noop: host %d, imp %d\n", ip->il_host,
32027727Skarels 		(u_short)ip->il_imp);
3216478Ssam }
3226478Ssam 
3236478Ssam imprfnm(ip)
3246478Ssam 	register struct imp_leader *ip;
3256478Ssam {
3266478Ssam 	printf("rfnm: htype=%x, source=%d/%d, link=",
3276478Ssam 		ip->il_htype, ip->il_host, ip->il_imp);
3286478Ssam 	if (ip->il_link == IMPLINK_IP)
3296478Ssam 		printf("ip,");
3306478Ssam 	else
33127727Skarels 		printf("%d,", ip->il_link);
3326478Ssam 	printf(" subtype=%x\n", ip->il_subtype);
3336478Ssam }
3346478Ssam 
3356478Ssam char *hostdead[] = {
3369195Ssam 	"#0",
3376478Ssam 	"ready-line negated",
3386478Ssam 	"tardy receiving messages",
3396478Ssam 	"ncc doesn't know host",
3406478Ssam 	"imp software won't allow messages",
3416478Ssam 	"host down for scheduled pm",
3426478Ssam 	"host down for hardware work",
3436478Ssam 	"host down for software work",
3446478Ssam 	"host down for emergency restart",
3456478Ssam 	"host down because of power outage",
3466478Ssam 	"host stopped at a breakpoint",
3476478Ssam 	"host down due to hardware failure",
3486478Ssam 	"host not scheduled to be up",
3499195Ssam 	"#13",
3509195Ssam 	"#14",
3516478Ssam 	"host in the process of coming up"
3526478Ssam };
3536478Ssam 
3546478Ssam imphostdead(ip)
3556478Ssam 	register struct imp_leader *ip;
3566478Ssam {
35727727Skarels 	printf("host %d/%d dead: ", ip->il_host, ip->il_imp);
3586478Ssam 	if (ip->il_link & IMP_DMASK)
3596478Ssam 		printf("down %s, ", down[ip->il_link & IMP_DMASK]);
3606478Ssam 	if (ip->il_subtype <= IMPHOST_COMINGUP)
3616478Ssam 		printf("%s\n", hostdead[ip->il_subtype]);
3626478Ssam 	else
3636478Ssam 		printf("subtype=%x\n", ip->il_subtype);
3646478Ssam }
3656478Ssam 
3666478Ssam char *hostunreach[] = {
3676478Ssam 	"destination imp can't be reached",
3686478Ssam 	"destination host isn't up",
3696478Ssam 	"host doesn't support long leader",
3706478Ssam 	"communication is prohibited"
3716478Ssam };
3726478Ssam 
3736478Ssam imphostunreach(ip)
3746478Ssam 	register struct imp_leader *ip;
3756478Ssam {
37627727Skarels 	printf("host %d/%d unreachable: ", ip->il_host, ip->il_imp);
3776478Ssam 	if (ip->il_subtype <= IMPREACH_PROHIBITED)
3786478Ssam 		printf("%s\n", hostunreach[ip->il_subtype]);
3796478Ssam 	else
3806478Ssam 		printf("subtype=%x\n", ip->il_subtype);
3816478Ssam }
3826478Ssam 
3836478Ssam impbaddata(ip)
3846478Ssam 	register struct imp_leader *ip;
3856478Ssam {
3866478Ssam 	printf("error in data: htype=%x, source=%d/%d, link=",
3876478Ssam 		ip->il_htype, ip->il_host, ip->il_imp);
3886478Ssam 	if (ip->il_link == IMPLINK_IP)
3896478Ssam 		printf("ip, ");
3906478Ssam 	else
39127727Skarels 		printf("%d, ", ip->il_link);
3926478Ssam 	printf("subtype=%x\n", ip->il_subtype);
3936478Ssam }
3946478Ssam 
3956478Ssam char *incomplete[] = {
3966478Ssam 	"host didn't take data fast enough",
3976478Ssam 	"message was too long",
3986478Ssam 	"message transmission time > 15 seconds",
3996478Ssam 	"imp/circuit failure",
4006478Ssam 	"no resources within 15 seconds",
4016478Ssam 	"source imp i/o failure during receipt"
4026478Ssam };
4036478Ssam 
4046478Ssam impincomplete(ip)
4056478Ssam 	register struct imp_leader *ip;
4066478Ssam {
4076478Ssam 	printf("incomplete: htype=%x, source=%d/%d, link=",
4086478Ssam 		ip->il_htype, ip->il_host, ip->il_imp);
4096478Ssam 	if (ip->il_link == IMPLINK_IP)
4106478Ssam 		printf("ip,");
4116478Ssam 	else
41227727Skarels 		printf("%d,", ip->il_link);
4136478Ssam 	if (ip->il_subtype <= IMPCOMPLETE_IMPIO)
4146478Ssam 		printf(" %s\n", incomplete[ip->il_subtype]);
4156478Ssam 	else
4166478Ssam 		printf(" subtype=%x\n", ip->il_subtype);
4176478Ssam }
4186478Ssam 
4196478Ssam impreset(ip)
4206478Ssam 	register struct imp_leader *ip;
4216478Ssam {
4226478Ssam 	printf("reset complete\n");
4236478Ssam }
4246478Ssam 
4256478Ssam char *retry[] = {
4266478Ssam 	"imp buffer wasn't available",
4276478Ssam 	"connection block unavailable"
4286478Ssam };
4296478Ssam 
4306478Ssam impretry(ip)
4316478Ssam 	register struct imp_leader *ip;
4326478Ssam {
4336478Ssam 	printf("refused, try again: ");
4346478Ssam 	if (ip->il_subtype <= IMPRETRY_BLOCK)
4356478Ssam 		printf("%s\n", retry[ip->il_subtype]);
4366478Ssam 	else
4376478Ssam 		printf("subtype=%x\n", ip->il_subtype);
4386478Ssam }
4396478Ssam 
4406478Ssam char *notify[] = {
4419195Ssam 	"#0",
4429195Ssam 	"#1",
4436478Ssam 	"connection not available",
4446478Ssam 	"reassembly space not available at destination",
4456478Ssam 	"message number not available",
4466478Ssam 	"transaction block for message not available"
4476478Ssam };
4486478Ssam 
4496478Ssam impnotify(ip)
4506478Ssam 	register struct imp_leader *ip;
4516478Ssam {
4526478Ssam 	printf("refused, will notify: ");
4536478Ssam 	if (ip->il_subtype <= 5)
4546478Ssam 		printf("%s\n", notify[ip->il_subtype]);
4556478Ssam 	else
4566478Ssam 		printf("subtype=%x\n", ip->il_subtype);
4576478Ssam }
4586478Ssam 
4596478Ssam imptrying(ip)
4606478Ssam 	register struct imp_leader *ip;
4616478Ssam {
4626478Ssam 	printf("refused, still trying\n");
4636478Ssam }
4646478Ssam 
4656478Ssam impready(ip)
4666478Ssam 	register struct imp_leader *ip;
4676478Ssam {
4686478Ssam 	printf("ready\n");
4696478Ssam }
4706478Ssam 
471*28904Skarels impundef(ip, len)
4726478Ssam 	register struct imp_leader *ip;
4736478Ssam {
4746478Ssam 	printf("<fmt=%x, net=%x, flags=%x, mtype=", ip->il_format,
4756478Ssam 		ip->il_network, ip->il_flags);
476*28904Skarels 	printf("%x, htype=%x,\n\t host=%d(x%x), imp=%d(x%x), link=",
477*28904Skarels 		ip->il_mtype, ip->il_htype, ip->il_host, ip->il_host,
478*28904Skarels 		ip->il_imp, ip->il_imp);
4796478Ssam 	if (ip->il_link == IMPLINK_IP)
4806478Ssam 		printf("ip,");
4816478Ssam 	else
482*28904Skarels 		printf("%d (x%x),", ip->il_link, ip->il_link);
483*28904Skarels 	printf(" subtype=%x", ip->il_subtype);
484*28904Skarels 	if (len >= sizeof(struct imp_leader) && ip->il_length)
485*28904Skarels 		printf(" len=%d bytes", ntohs((u_short)ip->il_length) >> 3);
486*28904Skarels 	printf(">\n");
4876478Ssam }
488