xref: /csrg-svn/old/implog/implog.c (revision 33455)
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*33455Skarels static char sccsid[] = "@(#)implog.c	5.7 (Berkeley) 02/08/88";
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 
26*33455Skarels #include <net/if.h>
27*33455Skarels 
289195Ssam #include <netinet/in.h>
29*33455Skarels #define	IMPMESSAGES
306478Ssam #define	IMPLEADERS
319195Ssam #include <netimp/if_imp.h>
326478Ssam 
336478Ssam #define	min(a, b)	((a) < (b) ? (a) : (b))
346478Ssam 
356478Ssam u_char	buf[1024];
366478Ssam int	showdata = 1;
376478Ssam int	showcontents = 0;
3827727Skarels int	rawheader = 0;
396478Ssam int	follow = 0;
406478Ssam int	link = -1;
416478Ssam int	host = -1;
426478Ssam int	imp = -1;
436478Ssam int	packettype = -1;
446478Ssam extern	int errno;
456478Ssam int	log;
466478Ssam char	*logfile = "/usr/adm/implog";
476478Ssam 
486478Ssam /*
496478Ssam  * Socket address, internet style, with
506478Ssam  * unused space taken by timestamp and packet
516478Ssam  * size.
526478Ssam  */
536478Ssam struct sockstamp {
546478Ssam 	short	sin_family;
556478Ssam 	u_short	sin_port;
566478Ssam 	struct	in_addr sin_addr;
576478Ssam 	time_t	sin_time;
586478Ssam 	int	sin_cc;
596478Ssam };
606478Ssam struct	sockstamp from;
616478Ssam 
626478Ssam main(argc, argv)
636478Ssam 	char *argv[];
646478Ssam {
656478Ssam 	struct stat b;
666478Ssam 	int size;
676478Ssam 	char *cp;
6822597Skarels 	int hostfrom, impfrom;
696478Ssam 
706478Ssam 	argc--, argv++;
716478Ssam 	while (argc > 0 && argv[0][0] == '-') {
726478Ssam 		if (strcmp(*argv, "-D") == 0) {
736478Ssam 			showdata = 0;
746478Ssam 			argv++, argc--;
756478Ssam 			continue;
766478Ssam 		}
776478Ssam 		if (strcmp(*argv, "-f") == 0) {
786478Ssam 			follow++;
796478Ssam 			argv++, argc--;
806478Ssam 			continue;
816478Ssam 		}
826478Ssam 		if (strcmp(*argv, "-c") == 0) {
836478Ssam 			showcontents++;
846478Ssam 			argv++, argc--;
856478Ssam 			continue;
866478Ssam 		}
8727727Skarels 		if (strcmp(*argv, "-r") == 0) {
8827727Skarels 			rawheader++;
8927727Skarels 			argv++, argc--;
9027727Skarels 			continue;
9127727Skarels 		}
926478Ssam 		if (strcmp(*argv, "-l") == 0) {
936478Ssam 			argc--, argv++;
946478Ssam 			if (argc > 0) {
956478Ssam 				link = atoi(*argv);
966478Ssam 				argc--, argv++;
976478Ssam 			} else
986478Ssam 				link = IMPLINK_IP;
996478Ssam 			continue;
1006478Ssam 		}
1016478Ssam 		if (strcmp(*argv, "-h") == 0) {
1026478Ssam 			argc--, argv++;
1036478Ssam 			if (argc < 1) {
1046478Ssam 				printf("-h: missing host #\n");
1056478Ssam 				exit(2);
1066478Ssam 			}
1076478Ssam 			host = atoi(*argv);
1086478Ssam 			argv++, argc--;
1096478Ssam 			continue;
1106478Ssam 		}
1116478Ssam 		if (strcmp(*argv, "-i") == 0) {
1126478Ssam 			argc--, argv++;
1136478Ssam 			if (argc < 1) {
1146478Ssam 				printf("-i: missing imp #\n");
1156478Ssam 				exit(2);
1166478Ssam 			}
1176478Ssam 			imp = atoi(*argv);
1186478Ssam 			argv++, argc--;
1196478Ssam 			continue;
1206478Ssam 		}
1216478Ssam 		if (strcmp(*argv, "-t") == 0) {
1226478Ssam 			argc--, argv++;;
1236478Ssam 			if (argc < 1) {
1246478Ssam 				printf("-t: missing packet type\n");
1256478Ssam 				exit(2);
1266478Ssam 			}
1276478Ssam 			packettype = atoi(*argv);
1286478Ssam 			argv++, argc--;;
1296478Ssam 			continue;
1306478Ssam 		}
13127727Skarels 		printf("usage: implog [ -D ] [ -c ] [ -f ] [ -r ] [-h #] [-i #] [ -t # ] [-l [#]] [logfile]\n");
1326478Ssam 		exit(2);
1336478Ssam 	}
1346478Ssam 	if (argc > 0)
1356478Ssam 		logfile = argv[0];
1366478Ssam 	log = open(logfile, 0);
1376478Ssam 	if (log < 0) {
1386478Ssam 		perror(logfile);
1396478Ssam 		exit(1);
1406478Ssam 	}
1416478Ssam 	fstat(log, &b);
1426478Ssam 	size = b.st_size;
1436478Ssam again:
1446478Ssam 	while (read(log, (char *)&from, sizeof(from)) == sizeof(from)) {
1456478Ssam 		if (from.sin_family == 0) {
1466478Ssam 			printf("restarted: %.24s\n", ctime(&from.sin_time));
1476478Ssam 			continue;
1486478Ssam 		}
14922597Skarels 		if (host >= 0) {
15022597Skarels 			long addr = ntohs(from.sin_addr.s_addr);
15122597Skarels 
15222597Skarels 			if (IN_CLASSA(addr)) {
15322597Skarels 				hostfrom = ((addr>>16) & 0xFF);
15422597Skarels 				impfrom = addr & 0xFF;
15522597Skarels 			} else if (IN_CLASSB(addr)) {
15622597Skarels 				hostfrom = ((addr>>8) & 0xFF);
15722597Skarels 				impfrom = addr & 0xFF;
15822597Skarels 			} else {
15922597Skarels 				hostfrom = ((addr>>4) & 0xF);
16022597Skarels 				impfrom = addr & 0xF;
16122597Skarels 			}
16222597Skarels 		}
16322597Skarels 		if (host >= 0 && hostfrom != host) {
1646478Ssam 			lseek(log, from.sin_cc, 1);
1656478Ssam 			continue;
1666478Ssam 		}
16722597Skarels 		if (imp >= 0 && impfrom != imp) {
16822597Skarels 			lseek(log, from.sin_cc, 1);
16922597Skarels 			continue;
1706478Ssam 		}
1716478Ssam 		process(log, &from);
1726478Ssam 	}
1736478Ssam 	while (follow) {
1746478Ssam 		fflush(stdout);
1756478Ssam 		sleep(5);
1766478Ssam 		fstat(log, &b);
1776478Ssam 		if (b.st_size > size) {
1786478Ssam 			size = b.st_size;
1796478Ssam 			goto again;
1806478Ssam 		}
1816478Ssam 	}
1826478Ssam }
1836478Ssam 
1846478Ssam int	impdata(), impbadleader(), impdown(), impnoop();
1856478Ssam int	imprfnm(), impincomplete(), imphostdead(), imphostunreach();
1866478Ssam int	impbaddata(), impreset(), impretry(), impnotify(), imptrying();
1876478Ssam int	impready(), impundef();
1886478Ssam 
1896478Ssam struct	messages {
1906478Ssam 	u_char	m_type;		/* type of message */
1916478Ssam 	int	(*m_func)();	/* routine to process message */
1926478Ssam } mtypes[] = {
1936478Ssam 	{ IMPTYPE_DATA,		impdata },
1946478Ssam 	{ IMPTYPE_BADLEADER,	impbadleader },
1956478Ssam 	{ IMPTYPE_DOWN,		impdown },
1966478Ssam 	{ IMPTYPE_NOOP,		impnoop },
1976478Ssam 	{ IMPTYPE_RFNM,		imprfnm },
1986478Ssam 	{ IMPTYPE_INCOMPLETE,	impincomplete },
1996478Ssam 	{ IMPTYPE_HOSTDEAD,	imphostdead },
2006478Ssam 	{ IMPTYPE_HOSTUNREACH,	imphostunreach },
2016478Ssam 	{ IMPTYPE_BADDATA,	impbaddata },
2026478Ssam 	{ IMPTYPE_RESET,	impreset },
2036478Ssam 	{ IMPTYPE_RETRY,	impretry },
2046478Ssam 	{ IMPTYPE_NOTIFY,	impnotify },
2056478Ssam 	{ IMPTYPE_TRYING,	imptrying },
2066478Ssam 	{ IMPTYPE_READY,	impready },
2076478Ssam 	{ -1,			impundef }
2086478Ssam };
2096478Ssam 
2106478Ssam /*
2116478Ssam  * Print a packet.
2126478Ssam  */
2136478Ssam process(l, f)
2146478Ssam 	int l;
2156478Ssam 	struct sockstamp *f;
2166478Ssam {
2176478Ssam 	register struct messages *mp;
2186478Ssam 	struct imp_leader *ip;
21927727Skarels 	int (*fn)();
2206478Ssam 
2216478Ssam 	if (read(l, (char *)buf, f->sin_cc) != f->sin_cc) {
2226478Ssam 		perror("read");
2236478Ssam 		return;
2246478Ssam 	}
2256478Ssam 	ip = (struct imp_leader *)buf;
22628904Skarels 	ip->il_imp = ntohs(ip->il_imp);
22727727Skarels 	if (ip->il_format != IMP_NFF)
22827727Skarels 		fn = impundef;
22927727Skarels 	else {
23033085Sbostic 		for (mp = mtypes; mp->m_type != (u_char)-1; mp++)
23127727Skarels 			if (mp->m_type == ip->il_mtype)
23227727Skarels 				break;
23327727Skarels 		fn = mp->m_func;
23427727Skarels 	}
23527727Skarels 	if (ip->il_mtype == IMPTYPE_DATA) {
2366478Ssam 		if (link >= 0 && ip->il_link != link)
2376478Ssam 			return;
2386478Ssam 		if (!showdata)
2396478Ssam 			return;
2406478Ssam 	}
24127727Skarels 	if (packettype >= 0 && ip->il_mtype != packettype)
2426478Ssam 		return;
2436478Ssam 	printf("%.24s: ", ctime(&f->sin_time));
24428904Skarels 	if (f->sin_cc < sizeof(struct control_leader))
24528904Skarels 		printf("(truncated header, %d bytes): ", f->sin_cc);
24627727Skarels 	(*fn)(ip, f->sin_cc);
24728904Skarels 	if (rawheader && fn != impundef) {
24828904Skarels 		putchar('\t');
24927727Skarels 		impundef(ip, f->sin_cc);
25028904Skarels 	}
2516478Ssam }
2526478Ssam 
2536478Ssam impdata(ip, cc)
2546478Ssam 	register struct imp_leader *ip;
2556478Ssam {
25627727Skarels 	printf("<DATA, source=%d/%d, link=", ip->il_host, (u_short)ip->il_imp);
2576478Ssam 	if (ip->il_link == IMPLINK_IP)
2586478Ssam 		printf("ip,");
2596478Ssam 	else
2606478Ssam 		printf("%d,", ip->il_link);
2619195Ssam 	printf(" len=%d bytes>\n", ntohs((u_short)ip->il_length) >> 3);
2626478Ssam 	if (showcontents) {
2636478Ssam 		register u_char *cp = ((u_char *)ip) + sizeof(*ip);
2646478Ssam 		register int i;
2656478Ssam 
2666478Ssam 		i = (ntohs(ip->il_length) >> 3) - sizeof(struct imp_leader);
2676478Ssam 		cc = min(i, cc);
2686478Ssam 		printf("data: (%d bytes)", cc);
2696478Ssam 		for (i = 0; i < cc; i++, cp++) {
2706478Ssam 			if (i % 25 == 0)
2716478Ssam 				printf("\n");
2726478Ssam 			printf("%02x ", *cp);
2736478Ssam 		}
2746478Ssam 		putchar('\n');
2756478Ssam 	}
2766478Ssam }
2776478Ssam 
2786478Ssam char *badleader[] = {
2796478Ssam 	"error flip-flop set",
2806478Ssam 	"message < 80 bits",
2816478Ssam 	"illegal type field",
2826478Ssam 	"opposite leader type"
2836478Ssam };
2846478Ssam 
2856478Ssam impbadleader(ip)
2866478Ssam 	register struct imp_leader *ip;
2876478Ssam {
2886478Ssam 	printf("bad leader: ");
2896478Ssam 	if (ip->il_subtype > IMPLEADER_OPPOSITE)
2906478Ssam 		printf("%x\n", ip->il_subtype);
2916478Ssam 	else
2926478Ssam 		printf("%s\n", badleader[ip->il_subtype]);
2936478Ssam }
2946478Ssam 
2956478Ssam impdown(ip)
2966478Ssam 	register struct imp_leader *ip;
2976478Ssam {
2986478Ssam 	int tdown, tbackup;
2996478Ssam 
300*33455Skarels 	printf("imp going down %s", impmessage[ip->il_link & IMP_DMASK]);
301*33455Skarels 	tdown = ((ip->il_link >> IMPDOWN_WHENSHIFT) & IMPDOWN_WHENMASK) *
302*33455Skarels 	    IMPDOWN_WHENUNIT;
303*33455Skarels 	if ((ip->il_link & IMP_DMASK) != IMPDOWN_GOING)
3046478Ssam 		printf(" in %d minutes", tdown);
305*33455Skarels 	tbackup = ip->il_subtype * IMPDOWN_WHENUNIT;
3066478Ssam 	printf(": back up ");
3076478Ssam 	if (tbackup)
3086478Ssam 		printf("%d minutes\n", tbackup);
3096478Ssam 	else
3106478Ssam 		printf("immediately\n");
3116478Ssam }
3126478Ssam 
3136478Ssam impnoop(ip)
3146478Ssam 	register struct imp_leader *ip;
3156478Ssam {
3169195Ssam 	printf("noop: host %d, imp %d\n", ip->il_host,
31727727Skarels 		(u_short)ip->il_imp);
3186478Ssam }
3196478Ssam 
3206478Ssam imprfnm(ip)
3216478Ssam 	register struct imp_leader *ip;
3226478Ssam {
3236478Ssam 	printf("rfnm: htype=%x, source=%d/%d, link=",
3246478Ssam 		ip->il_htype, ip->il_host, ip->il_imp);
3256478Ssam 	if (ip->il_link == IMPLINK_IP)
3266478Ssam 		printf("ip,");
3276478Ssam 	else
32827727Skarels 		printf("%d,", ip->il_link);
3296478Ssam 	printf(" subtype=%x\n", ip->il_subtype);
3306478Ssam }
3316478Ssam 
3326478Ssam char *hostdead[] = {
3339195Ssam 	"#0",
3346478Ssam 	"ready-line negated",
3356478Ssam 	"tardy receiving messages",
3366478Ssam 	"ncc doesn't know host",
3376478Ssam 	"imp software won't allow messages",
3386478Ssam 	"host down for scheduled pm",
3396478Ssam 	"host down for hardware work",
3406478Ssam 	"host down for software work",
3416478Ssam 	"host down for emergency restart",
3426478Ssam 	"host down because of power outage",
3436478Ssam 	"host stopped at a breakpoint",
3446478Ssam 	"host down due to hardware failure",
3456478Ssam 	"host not scheduled to be up",
3469195Ssam 	"#13",
3479195Ssam 	"#14",
3486478Ssam 	"host in the process of coming up"
3496478Ssam };
3506478Ssam 
3516478Ssam imphostdead(ip)
3526478Ssam 	register struct imp_leader *ip;
3536478Ssam {
35427727Skarels 	printf("host %d/%d dead: ", ip->il_host, ip->il_imp);
3556478Ssam 	if (ip->il_link & IMP_DMASK)
356*33455Skarels 		printf("down %s, ", impmessage[ip->il_link & IMP_DMASK]);
3576478Ssam 	if (ip->il_subtype <= IMPHOST_COMINGUP)
3586478Ssam 		printf("%s\n", hostdead[ip->il_subtype]);
3596478Ssam 	else
3606478Ssam 		printf("subtype=%x\n", ip->il_subtype);
3616478Ssam }
3626478Ssam 
3636478Ssam char *hostunreach[] = {
3646478Ssam 	"destination imp can't be reached",
3656478Ssam 	"destination host isn't up",
3666478Ssam 	"host doesn't support long leader",
3676478Ssam 	"communication is prohibited"
3686478Ssam };
3696478Ssam 
3706478Ssam imphostunreach(ip)
3716478Ssam 	register struct imp_leader *ip;
3726478Ssam {
37327727Skarels 	printf("host %d/%d unreachable: ", ip->il_host, ip->il_imp);
3746478Ssam 	if (ip->il_subtype <= IMPREACH_PROHIBITED)
3756478Ssam 		printf("%s\n", hostunreach[ip->il_subtype]);
3766478Ssam 	else
3776478Ssam 		printf("subtype=%x\n", ip->il_subtype);
3786478Ssam }
3796478Ssam 
3806478Ssam impbaddata(ip)
3816478Ssam 	register struct imp_leader *ip;
3826478Ssam {
3836478Ssam 	printf("error in data: htype=%x, source=%d/%d, link=",
3846478Ssam 		ip->il_htype, ip->il_host, ip->il_imp);
3856478Ssam 	if (ip->il_link == IMPLINK_IP)
3866478Ssam 		printf("ip, ");
3876478Ssam 	else
38827727Skarels 		printf("%d, ", ip->il_link);
3896478Ssam 	printf("subtype=%x\n", ip->il_subtype);
3906478Ssam }
3916478Ssam 
3926478Ssam char *incomplete[] = {
3936478Ssam 	"host didn't take data fast enough",
3946478Ssam 	"message was too long",
3956478Ssam 	"message transmission time > 15 seconds",
3966478Ssam 	"imp/circuit failure",
3976478Ssam 	"no resources within 15 seconds",
3986478Ssam 	"source imp i/o failure during receipt"
3996478Ssam };
4006478Ssam 
4016478Ssam impincomplete(ip)
4026478Ssam 	register struct imp_leader *ip;
4036478Ssam {
4046478Ssam 	printf("incomplete: htype=%x, source=%d/%d, link=",
4056478Ssam 		ip->il_htype, ip->il_host, ip->il_imp);
4066478Ssam 	if (ip->il_link == IMPLINK_IP)
4076478Ssam 		printf("ip,");
4086478Ssam 	else
40927727Skarels 		printf("%d,", ip->il_link);
4106478Ssam 	if (ip->il_subtype <= IMPCOMPLETE_IMPIO)
4116478Ssam 		printf(" %s\n", incomplete[ip->il_subtype]);
4126478Ssam 	else
4136478Ssam 		printf(" subtype=%x\n", ip->il_subtype);
4146478Ssam }
4156478Ssam 
4166478Ssam impreset(ip)
4176478Ssam 	register struct imp_leader *ip;
4186478Ssam {
4196478Ssam 	printf("reset complete\n");
4206478Ssam }
4216478Ssam 
4226478Ssam char *retry[] = {
4236478Ssam 	"imp buffer wasn't available",
4246478Ssam 	"connection block unavailable"
4256478Ssam };
4266478Ssam 
4276478Ssam impretry(ip)
4286478Ssam 	register struct imp_leader *ip;
4296478Ssam {
4306478Ssam 	printf("refused, try again: ");
4316478Ssam 	if (ip->il_subtype <= IMPRETRY_BLOCK)
4326478Ssam 		printf("%s\n", retry[ip->il_subtype]);
4336478Ssam 	else
4346478Ssam 		printf("subtype=%x\n", ip->il_subtype);
4356478Ssam }
4366478Ssam 
4376478Ssam char *notify[] = {
4389195Ssam 	"#0",
4399195Ssam 	"#1",
4406478Ssam 	"connection not available",
4416478Ssam 	"reassembly space not available at destination",
4426478Ssam 	"message number not available",
4436478Ssam 	"transaction block for message not available"
4446478Ssam };
4456478Ssam 
4466478Ssam impnotify(ip)
4476478Ssam 	register struct imp_leader *ip;
4486478Ssam {
4496478Ssam 	printf("refused, will notify: ");
4506478Ssam 	if (ip->il_subtype <= 5)
4516478Ssam 		printf("%s\n", notify[ip->il_subtype]);
4526478Ssam 	else
4536478Ssam 		printf("subtype=%x\n", ip->il_subtype);
4546478Ssam }
4556478Ssam 
4566478Ssam imptrying(ip)
4576478Ssam 	register struct imp_leader *ip;
4586478Ssam {
4596478Ssam 	printf("refused, still trying\n");
4606478Ssam }
4616478Ssam 
4626478Ssam impready(ip)
4636478Ssam 	register struct imp_leader *ip;
4646478Ssam {
4656478Ssam 	printf("ready\n");
4666478Ssam }
4676478Ssam 
46828904Skarels impundef(ip, len)
4696478Ssam 	register struct imp_leader *ip;
4706478Ssam {
4716478Ssam 	printf("<fmt=%x, net=%x, flags=%x, mtype=", ip->il_format,
4726478Ssam 		ip->il_network, ip->il_flags);
47328904Skarels 	printf("%x, htype=%x,\n\t host=%d(x%x), imp=%d(x%x), link=",
47428904Skarels 		ip->il_mtype, ip->il_htype, ip->il_host, ip->il_host,
47528904Skarels 		ip->il_imp, ip->il_imp);
4766478Ssam 	if (ip->il_link == IMPLINK_IP)
4776478Ssam 		printf("ip,");
4786478Ssam 	else
47928904Skarels 		printf("%d (x%x),", ip->il_link, ip->il_link);
48028904Skarels 	printf(" subtype=%x", ip->il_subtype);
48128904Skarels 	if (len >= sizeof(struct imp_leader) && ip->il_length)
48228904Skarels 		printf(" len=%d bytes", ntohs((u_short)ip->il_length) >> 3);
48328904Skarels 	printf(">\n");
4846478Ssam }
485