xref: /csrg-svn/old/implog/implog.c (revision 21138)
1*21138Sdist /*
2*21138Sdist  * Copyright (c) 1980 Regents of the University of California.
3*21138Sdist  * All rights reserved.  The Berkeley software License Agreement
4*21138Sdist  * specifies the terms and conditions for redistribution.
5*21138Sdist  */
6*21138Sdist 
79197Ssam #ifndef lint
8*21138Sdist char copyright[] =
9*21138Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\
10*21138Sdist  All rights reserved.\n";
11*21138Sdist #endif not lint
126478Ssam 
13*21138Sdist #ifndef lint
14*21138Sdist static char sccsid[] = "@(#)implog.c	5.1 (Berkeley) 05/28/85";
15*21138Sdist #endif not lint
16*21138Sdist 
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;
646478Ssam 
656478Ssam 	argc--, argv++;
666478Ssam 	while (argc > 0 && argv[0][0] == '-') {
676478Ssam 		if (strcmp(*argv, "-D") == 0) {
686478Ssam 			showdata = 0;
696478Ssam 			argv++, argc--;
706478Ssam 			continue;
716478Ssam 		}
726478Ssam 		if (strcmp(*argv, "-f") == 0) {
736478Ssam 			follow++;
746478Ssam 			argv++, argc--;
756478Ssam 			continue;
766478Ssam 		}
776478Ssam 		if (strcmp(*argv, "-c") == 0) {
786478Ssam 			showcontents++;
796478Ssam 			argv++, argc--;
806478Ssam 			continue;
816478Ssam 		}
826478Ssam 		if (strcmp(*argv, "-l") == 0) {
836478Ssam 			argc--, argv++;
846478Ssam 			if (argc > 0) {
856478Ssam 				link = atoi(*argv);
866478Ssam 				argc--, argv++;
876478Ssam 			} else
886478Ssam 				link = IMPLINK_IP;
896478Ssam 			continue;
906478Ssam 		}
916478Ssam 		if (strcmp(*argv, "-h") == 0) {
926478Ssam 			argc--, argv++;
936478Ssam 			if (argc < 1) {
946478Ssam 				printf("-h: missing host #\n");
956478Ssam 				exit(2);
966478Ssam 			}
976478Ssam 			host = atoi(*argv);
986478Ssam 			argv++, argc--;
996478Ssam 			continue;
1006478Ssam 		}
1016478Ssam 		if (strcmp(*argv, "-i") == 0) {
1026478Ssam 			argc--, argv++;
1036478Ssam 			if (argc < 1) {
1046478Ssam 				printf("-i: missing imp #\n");
1056478Ssam 				exit(2);
1066478Ssam 			}
1076478Ssam 			imp = atoi(*argv);
1086478Ssam 			argv++, argc--;
1096478Ssam 			continue;
1106478Ssam 		}
1116478Ssam 		if (strcmp(*argv, "-t") == 0) {
1126478Ssam 			argc--, argv++;;
1136478Ssam 			if (argc < 1) {
1146478Ssam 				printf("-t: missing packet type\n");
1156478Ssam 				exit(2);
1166478Ssam 			}
1176478Ssam 			packettype = atoi(*argv);
1186478Ssam 			argv++, argc--;;
1196478Ssam 			continue;
1206478Ssam 		}
1219195Ssam 		printf("usage: implog [ -D ] [ -c ] [ -f ] [-h #] [-i #] [ -t # ] [-l [#]] [logfile]\n");
1226478Ssam 		exit(2);
1236478Ssam 	}
1246478Ssam 	if (argc > 0)
1256478Ssam 		logfile = argv[0];
1266478Ssam 	log = open(logfile, 0);
1276478Ssam 	if (log < 0) {
1286478Ssam 		perror(logfile);
1296478Ssam 		exit(1);
1306478Ssam 	}
1316478Ssam 	fstat(log, &b);
1326478Ssam 	size = b.st_size;
1336478Ssam again:
1346478Ssam 	while (read(log, (char *)&from, sizeof(from)) == sizeof(from)) {
1356478Ssam 		if (from.sin_family == 0) {
1366478Ssam 			printf("restarted: %.24s\n", ctime(&from.sin_time));
1376478Ssam 			continue;
1386478Ssam 		}
1396478Ssam 		if (host >= 0 && from.sin_addr.s_host != host) {
1406478Ssam 			lseek(log, from.sin_cc, 1);
1416478Ssam 			continue;
1426478Ssam 		}
1436478Ssam 		if (imp >= 0) {
1446478Ssam 			from.sin_addr.s_imp = ntohs(from.sin_addr.s_imp);
1456478Ssam 			if (from.sin_addr.s_imp != imp) {
1466478Ssam 				lseek(log, from.sin_cc, 1);
1476478Ssam 				continue;
1486478Ssam 			}
1496478Ssam 		}
1506478Ssam 		process(log, &from);
1516478Ssam 	}
1526478Ssam 	while (follow) {
1536478Ssam 		fflush(stdout);
1546478Ssam 		sleep(5);
1556478Ssam 		fstat(log, &b);
1566478Ssam 		if (b.st_size > size) {
1576478Ssam 			size = b.st_size;
1586478Ssam 			goto again;
1596478Ssam 		}
1606478Ssam 	}
1616478Ssam }
1626478Ssam 
1636478Ssam int	impdata(), impbadleader(), impdown(), impnoop();
1646478Ssam int	imprfnm(), impincomplete(), imphostdead(), imphostunreach();
1656478Ssam int	impbaddata(), impreset(), impretry(), impnotify(), imptrying();
1666478Ssam int	impready(), impundef();
1676478Ssam 
1686478Ssam struct	messages {
1696478Ssam 	u_char	m_type;		/* type of message */
1706478Ssam 	int	(*m_func)();	/* routine to process message */
1716478Ssam } mtypes[] = {
1726478Ssam 	{ IMPTYPE_DATA,		impdata },
1736478Ssam 	{ IMPTYPE_BADLEADER,	impbadleader },
1746478Ssam 	{ IMPTYPE_DOWN,		impdown },
1756478Ssam 	{ IMPTYPE_NOOP,		impnoop },
1766478Ssam 	{ IMPTYPE_RFNM,		imprfnm },
1776478Ssam 	{ IMPTYPE_INCOMPLETE,	impincomplete },
1786478Ssam 	{ IMPTYPE_HOSTDEAD,	imphostdead },
1796478Ssam 	{ IMPTYPE_HOSTUNREACH,	imphostunreach },
1806478Ssam 	{ IMPTYPE_BADDATA,	impbaddata },
1816478Ssam 	{ IMPTYPE_RESET,	impreset },
1826478Ssam 	{ IMPTYPE_RETRY,	impretry },
1836478Ssam 	{ IMPTYPE_NOTIFY,	impnotify },
1846478Ssam 	{ IMPTYPE_TRYING,	imptrying },
1856478Ssam 	{ IMPTYPE_READY,	impready },
1866478Ssam 	{ -1,			impundef }
1876478Ssam };
1886478Ssam 
1896478Ssam /*
1906478Ssam  * Print a packet.
1916478Ssam  */
1926478Ssam process(l, f)
1936478Ssam 	int l;
1946478Ssam 	struct sockstamp *f;
1956478Ssam {
1966478Ssam 	register struct messages *mp;
1976478Ssam 	struct imp_leader *ip;
1986478Ssam 
1996478Ssam 	if (read(l, (char *)buf, f->sin_cc) != f->sin_cc) {
2006478Ssam 		perror("read");
2016478Ssam 		return;
2026478Ssam 	}
2036478Ssam 	ip = (struct imp_leader *)buf;
2049195Ssam 	ip->il_imp = ntohs((u_short)ip->il_imp);
2056478Ssam 	for (mp = mtypes; mp->m_type != -1; mp++)
2066478Ssam 		if (mp->m_type == ip->il_mtype)
2076478Ssam 			break;
2086478Ssam 	if (mp->m_type == IMPTYPE_DATA) {
2096478Ssam 		if (link >= 0 && ip->il_link != link)
2106478Ssam 			return;
2116478Ssam 		if (!showdata)
2126478Ssam 			return;
2136478Ssam 	}
2146478Ssam 	if (packettype >= 0 && mp->m_type != packettype)
2156478Ssam 		return;
2166478Ssam 	printf("%.24s: ", ctime(&f->sin_time));
2176478Ssam 	(*mp->m_func)(ip, f->sin_cc);
2186478Ssam }
2196478Ssam 
2206478Ssam impdata(ip, cc)
2216478Ssam 	register struct imp_leader *ip;
2226478Ssam {
2239195Ssam 	printf("<%d/%d, DATA, link=", ip->il_host, ntohs((u_short)ip->il_imp));
2246478Ssam 	if (ip->il_link == IMPLINK_IP)
2256478Ssam 		printf("ip,");
2266478Ssam 	else
2276478Ssam 		printf("%d,", ip->il_link);
2289195Ssam 	printf(" len=%d bytes>\n", ntohs((u_short)ip->il_length) >> 3);
2296478Ssam 	if (showcontents) {
2306478Ssam 		register u_char *cp = ((u_char *)ip) + sizeof(*ip);
2316478Ssam 		register int i;
2326478Ssam 
2336478Ssam 		i = (ntohs(ip->il_length) >> 3) - sizeof(struct imp_leader);
2346478Ssam 		cc = min(i, cc);
2356478Ssam 		printf("data: (%d bytes)", cc);
2366478Ssam 		for (i = 0; i < cc; i++, cp++) {
2376478Ssam 			if (i % 25 == 0)
2386478Ssam 				printf("\n");
2396478Ssam 			printf("%02x ", *cp);
2406478Ssam 		}
2416478Ssam 		putchar('\n');
2426478Ssam 	}
2436478Ssam }
2446478Ssam 
2456478Ssam char *badleader[] = {
2466478Ssam 	"error flip-flop set",
2476478Ssam 	"message < 80 bits",
2486478Ssam 	"illegal type field",
2496478Ssam 	"opposite leader type"
2506478Ssam };
2516478Ssam 
2526478Ssam impbadleader(ip)
2536478Ssam 	register struct imp_leader *ip;
2546478Ssam {
2556478Ssam 	printf("bad leader: ");
2566478Ssam 	if (ip->il_subtype > IMPLEADER_OPPOSITE)
2576478Ssam 		printf("%x\n", ip->il_subtype);
2586478Ssam 	else
2596478Ssam 		printf("%s\n", badleader[ip->il_subtype]);
2606478Ssam }
2616478Ssam 
2626478Ssam char *down[] = {
2636478Ssam 	"in 30 secs",
2646478Ssam 	"for hardware pm",
2656478Ssam 	"for software reload",
2666478Ssam 	"for emergency restart"
2676478Ssam };
2686478Ssam 
2696478Ssam impdown(ip)
2706478Ssam 	register struct imp_leader *ip;
2716478Ssam {
2726478Ssam 	int tdown, tbackup;
2736478Ssam 
2746478Ssam 	printf("imp going down %s", down[ip->il_link & IMP_DMASK]);
2756478Ssam 	tdown = ((ip->il_link >> 2) & 0xf) * 5;
2766478Ssam 	if (ip->il_link & IMP_DMASK)
2776478Ssam 		printf(" in %d minutes", tdown);
2786478Ssam 	tbackup = ip->il_subtype * 5;
2796478Ssam 	printf(": back up ");
2806478Ssam 	if (tbackup)
2816478Ssam 		printf("%d minutes\n", tbackup);
2826478Ssam 	else
2836478Ssam 		printf("immediately\n");
2846478Ssam }
2856478Ssam 
2866478Ssam impnoop(ip)
2876478Ssam 	register struct imp_leader *ip;
2886478Ssam {
2899195Ssam 	printf("noop: host %d, imp %d\n", ip->il_host,
2909195Ssam 		ntohs((u_short)ip->il_imp));
2916478Ssam }
2926478Ssam 
2936478Ssam imprfnm(ip)
2946478Ssam 	register struct imp_leader *ip;
2956478Ssam {
2966478Ssam 	printf("rfnm: htype=%x, source=%d/%d, link=",
2976478Ssam 		ip->il_htype, ip->il_host, ip->il_imp);
2986478Ssam 	if (ip->il_link == IMPLINK_IP)
2996478Ssam 		printf("ip,");
3006478Ssam 	else
3016478Ssam 		printf("%x,", ip->il_link);
3026478Ssam 	printf(" subtype=%x\n", ip->il_subtype);
3036478Ssam }
3046478Ssam 
3056478Ssam char *hostdead[] = {
3069195Ssam 	"#0",
3076478Ssam 	"ready-line negated",
3086478Ssam 	"tardy receiving messages",
3096478Ssam 	"ncc doesn't know host",
3106478Ssam 	"imp software won't allow messages",
3116478Ssam 	"host down for scheduled pm",
3126478Ssam 	"host down for hardware work",
3136478Ssam 	"host down for software work",
3146478Ssam 	"host down for emergency restart",
3156478Ssam 	"host down because of power outage",
3166478Ssam 	"host stopped at a breakpoint",
3176478Ssam 	"host down due to hardware failure",
3186478Ssam 	"host not scheduled to be up",
3199195Ssam 	"#13",
3209195Ssam 	"#14",
3216478Ssam 	"host in the process of coming up"
3226478Ssam };
3236478Ssam 
3246478Ssam imphostdead(ip)
3256478Ssam 	register struct imp_leader *ip;
3266478Ssam {
3276478Ssam 	printf("host dead: ");
3286478Ssam 	if (ip->il_link & IMP_DMASK)
3296478Ssam 		printf("down %s, ", down[ip->il_link & IMP_DMASK]);
3306478Ssam 	if (ip->il_subtype <= IMPHOST_COMINGUP)
3316478Ssam 		printf("%s\n", hostdead[ip->il_subtype]);
3326478Ssam 	else
3336478Ssam 		printf("subtype=%x\n", ip->il_subtype);
3346478Ssam }
3356478Ssam 
3366478Ssam char *hostunreach[] = {
3376478Ssam 	"destination imp can't be reached",
3386478Ssam 	"destination host isn't up",
3396478Ssam 	"host doesn't support long leader",
3406478Ssam 	"communication is prohibited"
3416478Ssam };
3426478Ssam 
3436478Ssam imphostunreach(ip)
3446478Ssam 	register struct imp_leader *ip;
3456478Ssam {
3466478Ssam 	printf("host unreachable: ");
3476478Ssam 	if (ip->il_subtype <= IMPREACH_PROHIBITED)
3486478Ssam 		printf("%s\n", hostunreach[ip->il_subtype]);
3496478Ssam 	else
3506478Ssam 		printf("subtype=%x\n", ip->il_subtype);
3516478Ssam }
3526478Ssam 
3536478Ssam impbaddata(ip)
3546478Ssam 	register struct imp_leader *ip;
3556478Ssam {
3566478Ssam 	printf("error in data: htype=%x, source=%d/%d, link=",
3576478Ssam 		ip->il_htype, ip->il_host, ip->il_imp);
3586478Ssam 	if (ip->il_link == IMPLINK_IP)
3596478Ssam 		printf("ip, ");
3606478Ssam 	else
3616478Ssam 		printf("%x, ", ip->il_link);
3626478Ssam 	printf("subtype=%x\n", ip->il_subtype);
3636478Ssam }
3646478Ssam 
3656478Ssam char *incomplete[] = {
3666478Ssam 	"host didn't take data fast enough",
3676478Ssam 	"message was too long",
3686478Ssam 	"message transmission time > 15 seconds",
3696478Ssam 	"imp/circuit failure",
3706478Ssam 	"no resources within 15 seconds",
3716478Ssam 	"source imp i/o failure during receipt"
3726478Ssam };
3736478Ssam 
3746478Ssam impincomplete(ip)
3756478Ssam 	register struct imp_leader *ip;
3766478Ssam {
3776478Ssam 	printf("incomplete: htype=%x, source=%d/%d, link=",
3786478Ssam 		ip->il_htype, ip->il_host, ip->il_imp);
3796478Ssam 	if (ip->il_link == IMPLINK_IP)
3806478Ssam 		printf("ip,");
3816478Ssam 	else
3826478Ssam 		printf("%x,", ip->il_link);
3836478Ssam 	if (ip->il_subtype <= IMPCOMPLETE_IMPIO)
3846478Ssam 		printf(" %s\n", incomplete[ip->il_subtype]);
3856478Ssam 	else
3866478Ssam 		printf(" subtype=%x\n", ip->il_subtype);
3876478Ssam }
3886478Ssam 
3896478Ssam impreset(ip)
3906478Ssam 	register struct imp_leader *ip;
3916478Ssam {
3926478Ssam 	printf("reset complete\n");
3936478Ssam }
3946478Ssam 
3956478Ssam char *retry[] = {
3966478Ssam 	"imp buffer wasn't available",
3976478Ssam 	"connection block unavailable"
3986478Ssam };
3996478Ssam 
4006478Ssam impretry(ip)
4016478Ssam 	register struct imp_leader *ip;
4026478Ssam {
4036478Ssam 	printf("refused, try again: ");
4046478Ssam 	if (ip->il_subtype <= IMPRETRY_BLOCK)
4056478Ssam 		printf("%s\n", retry[ip->il_subtype]);
4066478Ssam 	else
4076478Ssam 		printf("subtype=%x\n", ip->il_subtype);
4086478Ssam }
4096478Ssam 
4106478Ssam char *notify[] = {
4119195Ssam 	"#0",
4129195Ssam 	"#1",
4136478Ssam 	"connection not available",
4146478Ssam 	"reassembly space not available at destination",
4156478Ssam 	"message number not available",
4166478Ssam 	"transaction block for message not available"
4176478Ssam };
4186478Ssam 
4196478Ssam impnotify(ip)
4206478Ssam 	register struct imp_leader *ip;
4216478Ssam {
4226478Ssam 	printf("refused, will notify: ");
4236478Ssam 	if (ip->il_subtype <= 5)
4246478Ssam 		printf("%s\n", notify[ip->il_subtype]);
4256478Ssam 	else
4266478Ssam 		printf("subtype=%x\n", ip->il_subtype);
4276478Ssam }
4286478Ssam 
4296478Ssam imptrying(ip)
4306478Ssam 	register struct imp_leader *ip;
4316478Ssam {
4326478Ssam 	printf("refused, still trying\n");
4336478Ssam }
4346478Ssam 
4356478Ssam impready(ip)
4366478Ssam 	register struct imp_leader *ip;
4376478Ssam {
4386478Ssam 	printf("ready\n");
4396478Ssam }
4406478Ssam 
4416478Ssam impundef(ip)
4426478Ssam 	register struct imp_leader *ip;
4436478Ssam {
4446478Ssam 	printf("<fmt=%x, net=%x, flags=%x, mtype=", ip->il_format,
4456478Ssam 		ip->il_network, ip->il_flags);
4466478Ssam 	printf("%x, htype=%x, host=%x, imp=%x, link=", ip->il_mtype,
4476478Ssam 		ip->il_htype, ip->il_host, ip->il_imp);
4486478Ssam 	if (ip->il_link == IMPLINK_IP)
4496478Ssam 		printf("ip,");
4506478Ssam 	else
4516478Ssam 		printf("%x,", ip->il_link);
4526478Ssam 	printf(" subtype=%x>\n", ip->il_subtype);
4536478Ssam }
454