xref: /csrg-svn/old/implog/implog.c (revision 34772)
121138Sdist /*
2*34772Sbostic  * Copyright (c) 1983, 1988 Regents of the University of California.
333457Skarels  * All rights reserved.
433457Skarels  *
533457Skarels  * Redistribution and use in source and binary forms are permitted
6*34772Sbostic  * provided that the above copyright notice and this paragraph are
7*34772Sbostic  * duplicated in all such forms and that any documentation,
8*34772Sbostic  * advertising materials, and other materials related to such
9*34772Sbostic  * distribution and use acknowledge that the software was developed
10*34772Sbostic  * by the University of California, Berkeley.  The name of the
11*34772Sbostic  * University may not be used to endorse or promote products derived
12*34772Sbostic  * from this software without specific prior written permission.
13*34772Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14*34772Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15*34772Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1621138Sdist  */
1721138Sdist 
189197Ssam #ifndef lint
1921138Sdist char copyright[] =
20*34772Sbostic "@(#) Copyright (c) 1983, 1988 Regents of the University of California.\n\
2121138Sdist  All rights reserved.\n";
22*34772Sbostic #endif /* not lint */
236478Ssam 
2421138Sdist #ifndef lint
25*34772Sbostic static char sccsid[] = "@(#)implog.c	5.10 (Berkeley) 06/18/88";
26*34772Sbostic #endif /* not lint */
2721138Sdist 
286478Ssam #include <stdio.h>
296478Ssam #include <signal.h>
306478Ssam #include <sgtty.h>
319195Ssam 
3213600Ssam #include <sys/time.h>
336478Ssam #include <sys/types.h>
3434037Skarels #include <sys/file.h>
356478Ssam #include <sys/stat.h>
366478Ssam #include <sys/socket.h>
379195Ssam 
3833455Skarels #include <net/if.h>
3933455Skarels 
409195Ssam #include <netinet/in.h>
4133455Skarels #define	IMPMESSAGES
426478Ssam #define	IMPLEADERS
439195Ssam #include <netimp/if_imp.h>
446478Ssam 
456478Ssam #define	min(a, b)	((a) < (b) ? (a) : (b))
466478Ssam 
476478Ssam u_char	buf[1024];
486478Ssam int	showdata = 1;
496478Ssam int	showcontents = 0;
5027727Skarels int	rawheader = 0;
516478Ssam int	follow = 0;
5234037Skarels int	skip = 0;
536478Ssam int	link = -1;
546478Ssam int	host = -1;
556478Ssam int	imp = -1;
566478Ssam int	packettype = -1;
576478Ssam extern	int errno;
586478Ssam int	log;
596478Ssam char	*logfile = "/usr/adm/implog";
606478Ssam 
616478Ssam /*
626478Ssam  * Socket address, internet style, with
636478Ssam  * unused space taken by timestamp and packet
646478Ssam  * size.
656478Ssam  */
666478Ssam struct sockstamp {
676478Ssam 	short	sin_family;
686478Ssam 	u_short	sin_port;
696478Ssam 	struct	in_addr sin_addr;
706478Ssam 	time_t	sin_time;
716478Ssam 	int	sin_cc;
726478Ssam };
736478Ssam struct	sockstamp from;
746478Ssam 
756478Ssam main(argc, argv)
766478Ssam 	char *argv[];
776478Ssam {
786478Ssam 	struct stat b;
7934037Skarels 	off_t size;
806478Ssam 	char *cp;
8122597Skarels 	int hostfrom, impfrom;
826478Ssam 
836478Ssam 	argc--, argv++;
846478Ssam 	while (argc > 0 && argv[0][0] == '-') {
856478Ssam 		if (strcmp(*argv, "-D") == 0) {
866478Ssam 			showdata = 0;
876478Ssam 			argv++, argc--;
886478Ssam 			continue;
896478Ssam 		}
906478Ssam 		if (strcmp(*argv, "-f") == 0) {
916478Ssam 			follow++;
926478Ssam 			argv++, argc--;
936478Ssam 			continue;
946478Ssam 		}
9534037Skarels 		if (strcmp(*argv, "-F") == 0) {
9634037Skarels 			skip++;
9734037Skarels 			follow++;
9834037Skarels 			argv++, argc--;
9934037Skarels 			continue;
10034037Skarels 		}
1016478Ssam 		if (strcmp(*argv, "-c") == 0) {
1026478Ssam 			showcontents++;
1036478Ssam 			argv++, argc--;
1046478Ssam 			continue;
1056478Ssam 		}
10627727Skarels 		if (strcmp(*argv, "-r") == 0) {
10727727Skarels 			rawheader++;
10827727Skarels 			argv++, argc--;
10927727Skarels 			continue;
11027727Skarels 		}
1116478Ssam 		if (strcmp(*argv, "-l") == 0) {
1126478Ssam 			argc--, argv++;
1136478Ssam 			if (argc > 0) {
1146478Ssam 				link = atoi(*argv);
1156478Ssam 				argc--, argv++;
1166478Ssam 			} else
1176478Ssam 				link = IMPLINK_IP;
1186478Ssam 			continue;
1196478Ssam 		}
1206478Ssam 		if (strcmp(*argv, "-h") == 0) {
1216478Ssam 			argc--, argv++;
1226478Ssam 			if (argc < 1) {
1236478Ssam 				printf("-h: missing host #\n");
1246478Ssam 				exit(2);
1256478Ssam 			}
1266478Ssam 			host = atoi(*argv);
1276478Ssam 			argv++, argc--;
1286478Ssam 			continue;
1296478Ssam 		}
1306478Ssam 		if (strcmp(*argv, "-i") == 0) {
1316478Ssam 			argc--, argv++;
1326478Ssam 			if (argc < 1) {
1336478Ssam 				printf("-i: missing imp #\n");
1346478Ssam 				exit(2);
1356478Ssam 			}
1366478Ssam 			imp = atoi(*argv);
1376478Ssam 			argv++, argc--;
1386478Ssam 			continue;
1396478Ssam 		}
1406478Ssam 		if (strcmp(*argv, "-t") == 0) {
1416478Ssam 			argc--, argv++;;
1426478Ssam 			if (argc < 1) {
1436478Ssam 				printf("-t: missing packet type\n");
1446478Ssam 				exit(2);
1456478Ssam 			}
1466478Ssam 			packettype = atoi(*argv);
1476478Ssam 			argv++, argc--;;
1486478Ssam 			continue;
1496478Ssam 		}
15034037Skarels 		printf("usage: implog [ -D ] [ -c ] [ -f ] [ -F ] [ -r ] [-h #] [-i #] [ -t # ] [-l [#]] [logfile]\n");
1516478Ssam 		exit(2);
1526478Ssam 	}
1536478Ssam 	if (argc > 0)
1546478Ssam 		logfile = argv[0];
1556478Ssam 	log = open(logfile, 0);
1566478Ssam 	if (log < 0) {
1576478Ssam 		perror(logfile);
1586478Ssam 		exit(1);
1596478Ssam 	}
1606478Ssam 	fstat(log, &b);
1616478Ssam 	size = b.st_size;
16234037Skarels 	if (skip)
16334037Skarels 		(void) lseek(log, size, L_SET);
1646478Ssam again:
1656478Ssam 	while (read(log, (char *)&from, sizeof(from)) == sizeof(from)) {
1666478Ssam 		if (from.sin_family == 0) {
1676478Ssam 			printf("restarted: %.24s\n", ctime(&from.sin_time));
1686478Ssam 			continue;
1696478Ssam 		}
17022597Skarels 		if (host >= 0) {
17122597Skarels 			long addr = ntohs(from.sin_addr.s_addr);
17222597Skarels 
17322597Skarels 			if (IN_CLASSA(addr)) {
17422597Skarels 				hostfrom = ((addr>>16) & 0xFF);
17522597Skarels 				impfrom = addr & 0xFF;
17622597Skarels 			} else if (IN_CLASSB(addr)) {
17722597Skarels 				hostfrom = ((addr>>8) & 0xFF);
17822597Skarels 				impfrom = addr & 0xFF;
17922597Skarels 			} else {
18022597Skarels 				hostfrom = ((addr>>4) & 0xF);
18122597Skarels 				impfrom = addr & 0xF;
18222597Skarels 			}
18322597Skarels 		}
18422597Skarels 		if (host >= 0 && hostfrom != host) {
1856478Ssam 			lseek(log, from.sin_cc, 1);
1866478Ssam 			continue;
1876478Ssam 		}
18822597Skarels 		if (imp >= 0 && impfrom != imp) {
18922597Skarels 			lseek(log, from.sin_cc, 1);
19022597Skarels 			continue;
1916478Ssam 		}
1926478Ssam 		process(log, &from);
1936478Ssam 	}
1946478Ssam 	while (follow) {
1956478Ssam 		fflush(stdout);
1966478Ssam 		sleep(5);
1976478Ssam 		fstat(log, &b);
1986478Ssam 		if (b.st_size > size) {
1996478Ssam 			size = b.st_size;
2006478Ssam 			goto again;
2016478Ssam 		}
2026478Ssam 	}
2036478Ssam }
2046478Ssam 
2056478Ssam int	impdata(), impbadleader(), impdown(), impnoop();
2066478Ssam int	imprfnm(), impincomplete(), imphostdead(), imphostunreach();
2076478Ssam int	impbaddata(), impreset(), impretry(), impnotify(), imptrying();
2086478Ssam int	impready(), impundef();
2096478Ssam 
2106478Ssam struct	messages {
2116478Ssam 	u_char	m_type;		/* type of message */
2126478Ssam 	int	(*m_func)();	/* routine to process message */
2136478Ssam } mtypes[] = {
2146478Ssam 	{ IMPTYPE_DATA,		impdata },
2156478Ssam 	{ IMPTYPE_BADLEADER,	impbadleader },
2166478Ssam 	{ IMPTYPE_DOWN,		impdown },
2176478Ssam 	{ IMPTYPE_NOOP,		impnoop },
2186478Ssam 	{ IMPTYPE_RFNM,		imprfnm },
2196478Ssam 	{ IMPTYPE_INCOMPLETE,	impincomplete },
2206478Ssam 	{ IMPTYPE_HOSTDEAD,	imphostdead },
2216478Ssam 	{ IMPTYPE_HOSTUNREACH,	imphostunreach },
2226478Ssam 	{ IMPTYPE_BADDATA,	impbaddata },
2236478Ssam 	{ IMPTYPE_RESET,	impreset },
2246478Ssam 	{ IMPTYPE_RETRY,	impretry },
2256478Ssam 	{ IMPTYPE_NOTIFY,	impnotify },
2266478Ssam 	{ IMPTYPE_TRYING,	imptrying },
2276478Ssam 	{ IMPTYPE_READY,	impready },
2286478Ssam 	{ -1,			impundef }
2296478Ssam };
2306478Ssam 
2316478Ssam /*
2326478Ssam  * Print a packet.
2336478Ssam  */
2346478Ssam process(l, f)
2356478Ssam 	int l;
2366478Ssam 	struct sockstamp *f;
2376478Ssam {
2386478Ssam 	register struct messages *mp;
2396478Ssam 	struct imp_leader *ip;
24027727Skarels 	int (*fn)();
2416478Ssam 
2426478Ssam 	if (read(l, (char *)buf, f->sin_cc) != f->sin_cc) {
2436478Ssam 		perror("read");
2446478Ssam 		return;
2456478Ssam 	}
2466478Ssam 	ip = (struct imp_leader *)buf;
24728904Skarels 	ip->il_imp = ntohs(ip->il_imp);
24827727Skarels 	if (ip->il_format != IMP_NFF)
24927727Skarels 		fn = impundef;
25027727Skarels 	else {
25133085Sbostic 		for (mp = mtypes; mp->m_type != (u_char)-1; mp++)
25227727Skarels 			if (mp->m_type == ip->il_mtype)
25327727Skarels 				break;
25427727Skarels 		fn = mp->m_func;
25527727Skarels 	}
25627727Skarels 	if (ip->il_mtype == IMPTYPE_DATA) {
2576478Ssam 		if (link >= 0 && ip->il_link != link)
2586478Ssam 			return;
2596478Ssam 		if (!showdata)
2606478Ssam 			return;
2616478Ssam 	}
26227727Skarels 	if (packettype >= 0 && ip->il_mtype != packettype)
2636478Ssam 		return;
2646478Ssam 	printf("%.24s: ", ctime(&f->sin_time));
26528904Skarels 	if (f->sin_cc < sizeof(struct control_leader))
26628904Skarels 		printf("(truncated header, %d bytes): ", f->sin_cc);
26727727Skarels 	(*fn)(ip, f->sin_cc);
26828904Skarels 	if (rawheader && fn != impundef) {
26928904Skarels 		putchar('\t');
27027727Skarels 		impundef(ip, f->sin_cc);
27128904Skarels 	}
2726478Ssam }
2736478Ssam 
2746478Ssam impdata(ip, cc)
2756478Ssam 	register struct imp_leader *ip;
2766478Ssam {
27727727Skarels 	printf("<DATA, source=%d/%d, link=", ip->il_host, (u_short)ip->il_imp);
2786478Ssam 	if (ip->il_link == IMPLINK_IP)
2796478Ssam 		printf("ip,");
2806478Ssam 	else
2816478Ssam 		printf("%d,", ip->il_link);
2829195Ssam 	printf(" len=%d bytes>\n", ntohs((u_short)ip->il_length) >> 3);
2836478Ssam 	if (showcontents) {
2846478Ssam 		register u_char *cp = ((u_char *)ip) + sizeof(*ip);
2856478Ssam 		register int i;
2866478Ssam 
2876478Ssam 		i = (ntohs(ip->il_length) >> 3) - sizeof(struct imp_leader);
2886478Ssam 		cc = min(i, cc);
2896478Ssam 		printf("data: (%d bytes)", cc);
2906478Ssam 		for (i = 0; i < cc; i++, cp++) {
2916478Ssam 			if (i % 25 == 0)
2926478Ssam 				printf("\n");
2936478Ssam 			printf("%02x ", *cp);
2946478Ssam 		}
2956478Ssam 		putchar('\n');
2966478Ssam 	}
2976478Ssam }
2986478Ssam 
2996478Ssam char *badleader[] = {
3006478Ssam 	"error flip-flop set",
3016478Ssam 	"message < 80 bits",
3026478Ssam 	"illegal type field",
3036478Ssam 	"opposite leader type"
3046478Ssam };
3056478Ssam 
3066478Ssam impbadleader(ip)
3076478Ssam 	register struct imp_leader *ip;
3086478Ssam {
3096478Ssam 	printf("bad leader: ");
3106478Ssam 	if (ip->il_subtype > IMPLEADER_OPPOSITE)
3116478Ssam 		printf("%x\n", ip->il_subtype);
3126478Ssam 	else
3136478Ssam 		printf("%s\n", badleader[ip->il_subtype]);
3146478Ssam }
3156478Ssam 
3166478Ssam impdown(ip)
3176478Ssam 	register struct imp_leader *ip;
3186478Ssam {
3196478Ssam 	int tdown, tbackup;
3206478Ssam 
32133455Skarels 	printf("imp going down %s", impmessage[ip->il_link & IMP_DMASK]);
32233455Skarels 	tdown = ((ip->il_link >> IMPDOWN_WHENSHIFT) & IMPDOWN_WHENMASK) *
32333455Skarels 	    IMPDOWN_WHENUNIT;
32433455Skarels 	if ((ip->il_link & IMP_DMASK) != IMPDOWN_GOING)
3256478Ssam 		printf(" in %d minutes", tdown);
32633455Skarels 	tbackup = ip->il_subtype * IMPDOWN_WHENUNIT;
3276478Ssam 	printf(": back up ");
3286478Ssam 	if (tbackup)
3296478Ssam 		printf("%d minutes\n", tbackup);
3306478Ssam 	else
3316478Ssam 		printf("immediately\n");
3326478Ssam }
3336478Ssam 
3346478Ssam impnoop(ip)
3356478Ssam 	register struct imp_leader *ip;
3366478Ssam {
3379195Ssam 	printf("noop: host %d, imp %d\n", ip->il_host,
33827727Skarels 		(u_short)ip->il_imp);
3396478Ssam }
3406478Ssam 
3416478Ssam imprfnm(ip)
3426478Ssam 	register struct imp_leader *ip;
3436478Ssam {
3446478Ssam 	printf("rfnm: 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
34927727Skarels 		printf("%d,", ip->il_link);
3506478Ssam 	printf(" subtype=%x\n", ip->il_subtype);
3516478Ssam }
3526478Ssam 
3536478Ssam char *hostdead[] = {
3549195Ssam 	"#0",
3556478Ssam 	"ready-line negated",
3566478Ssam 	"tardy receiving messages",
3576478Ssam 	"ncc doesn't know host",
3586478Ssam 	"imp software won't allow messages",
3596478Ssam 	"host down for scheduled pm",
3606478Ssam 	"host down for hardware work",
3616478Ssam 	"host down for software work",
3626478Ssam 	"host down for emergency restart",
3636478Ssam 	"host down because of power outage",
3646478Ssam 	"host stopped at a breakpoint",
3656478Ssam 	"host down due to hardware failure",
3666478Ssam 	"host not scheduled to be up",
3679195Ssam 	"#13",
3689195Ssam 	"#14",
3696478Ssam 	"host in the process of coming up"
3706478Ssam };
3716478Ssam 
3726478Ssam imphostdead(ip)
3736478Ssam 	register struct imp_leader *ip;
3746478Ssam {
37527727Skarels 	printf("host %d/%d dead: ", ip->il_host, ip->il_imp);
3766478Ssam 	if (ip->il_link & IMP_DMASK)
37733455Skarels 		printf("down %s, ", impmessage[ip->il_link & IMP_DMASK]);
3786478Ssam 	if (ip->il_subtype <= IMPHOST_COMINGUP)
3796478Ssam 		printf("%s\n", hostdead[ip->il_subtype]);
3806478Ssam 	else
3816478Ssam 		printf("subtype=%x\n", ip->il_subtype);
3826478Ssam }
3836478Ssam 
3846478Ssam char *hostunreach[] = {
3856478Ssam 	"destination imp can't be reached",
3866478Ssam 	"destination host isn't up",
3876478Ssam 	"host doesn't support long leader",
3886478Ssam 	"communication is prohibited"
3896478Ssam };
3906478Ssam 
3916478Ssam imphostunreach(ip)
3926478Ssam 	register struct imp_leader *ip;
3936478Ssam {
39427727Skarels 	printf("host %d/%d unreachable: ", ip->il_host, ip->il_imp);
3956478Ssam 	if (ip->il_subtype <= IMPREACH_PROHIBITED)
3966478Ssam 		printf("%s\n", hostunreach[ip->il_subtype]);
3976478Ssam 	else
3986478Ssam 		printf("subtype=%x\n", ip->il_subtype);
3996478Ssam }
4006478Ssam 
4016478Ssam impbaddata(ip)
4026478Ssam 	register struct imp_leader *ip;
4036478Ssam {
4046478Ssam 	printf("error in data: 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 	printf("subtype=%x\n", ip->il_subtype);
4116478Ssam }
4126478Ssam 
4136478Ssam char *incomplete[] = {
4146478Ssam 	"host didn't take data fast enough",
4156478Ssam 	"message was too long",
4166478Ssam 	"message transmission time > 15 seconds",
4176478Ssam 	"imp/circuit failure",
4186478Ssam 	"no resources within 15 seconds",
4196478Ssam 	"source imp i/o failure during receipt"
4206478Ssam };
4216478Ssam 
4226478Ssam impincomplete(ip)
4236478Ssam 	register struct imp_leader *ip;
4246478Ssam {
4256478Ssam 	printf("incomplete: htype=%x, source=%d/%d, link=",
4266478Ssam 		ip->il_htype, ip->il_host, ip->il_imp);
4276478Ssam 	if (ip->il_link == IMPLINK_IP)
4286478Ssam 		printf("ip,");
4296478Ssam 	else
43027727Skarels 		printf("%d,", ip->il_link);
4316478Ssam 	if (ip->il_subtype <= IMPCOMPLETE_IMPIO)
4326478Ssam 		printf(" %s\n", incomplete[ip->il_subtype]);
4336478Ssam 	else
4346478Ssam 		printf(" subtype=%x\n", ip->il_subtype);
4356478Ssam }
4366478Ssam 
4376478Ssam impreset(ip)
4386478Ssam 	register struct imp_leader *ip;
4396478Ssam {
4406478Ssam 	printf("reset complete\n");
4416478Ssam }
4426478Ssam 
4436478Ssam char *retry[] = {
4446478Ssam 	"imp buffer wasn't available",
4456478Ssam 	"connection block unavailable"
4466478Ssam };
4476478Ssam 
4486478Ssam impretry(ip)
4496478Ssam 	register struct imp_leader *ip;
4506478Ssam {
4516478Ssam 	printf("refused, try again: ");
4526478Ssam 	if (ip->il_subtype <= IMPRETRY_BLOCK)
4536478Ssam 		printf("%s\n", retry[ip->il_subtype]);
4546478Ssam 	else
4556478Ssam 		printf("subtype=%x\n", ip->il_subtype);
4566478Ssam }
4576478Ssam 
4586478Ssam char *notify[] = {
4599195Ssam 	"#0",
4609195Ssam 	"#1",
4616478Ssam 	"connection not available",
4626478Ssam 	"reassembly space not available at destination",
4636478Ssam 	"message number not available",
4646478Ssam 	"transaction block for message not available"
4656478Ssam };
4666478Ssam 
4676478Ssam impnotify(ip)
4686478Ssam 	register struct imp_leader *ip;
4696478Ssam {
4706478Ssam 	printf("refused, will notify: ");
4716478Ssam 	if (ip->il_subtype <= 5)
4726478Ssam 		printf("%s\n", notify[ip->il_subtype]);
4736478Ssam 	else
4746478Ssam 		printf("subtype=%x\n", ip->il_subtype);
4756478Ssam }
4766478Ssam 
4776478Ssam imptrying(ip)
4786478Ssam 	register struct imp_leader *ip;
4796478Ssam {
4806478Ssam 	printf("refused, still trying\n");
4816478Ssam }
4826478Ssam 
4836478Ssam impready(ip)
4846478Ssam 	register struct imp_leader *ip;
4856478Ssam {
4866478Ssam 	printf("ready\n");
4876478Ssam }
4886478Ssam 
48928904Skarels impundef(ip, len)
4906478Ssam 	register struct imp_leader *ip;
4916478Ssam {
4926478Ssam 	printf("<fmt=%x, net=%x, flags=%x, mtype=", ip->il_format,
4936478Ssam 		ip->il_network, ip->il_flags);
49428904Skarels 	printf("%x, htype=%x,\n\t host=%d(x%x), imp=%d(x%x), link=",
49528904Skarels 		ip->il_mtype, ip->il_htype, ip->il_host, ip->il_host,
49628904Skarels 		ip->il_imp, ip->il_imp);
4976478Ssam 	if (ip->il_link == IMPLINK_IP)
4986478Ssam 		printf("ip,");
4996478Ssam 	else
50028904Skarels 		printf("%d (x%x),", ip->il_link, ip->il_link);
50128904Skarels 	printf(" subtype=%x", ip->il_subtype);
50228904Skarels 	if (len >= sizeof(struct imp_leader) && ip->il_length)
50328904Skarels 		printf(" len=%d bytes", ntohs((u_short)ip->il_length) >> 3);
50428904Skarels 	printf(">\n");
5056478Ssam }
506