xref: /csrg-svn/old/implog/implog.c (revision 47697)
121138Sdist /*
234772Sbostic  * Copyright (c) 1983, 1988 Regents of the University of California.
333457Skarels  * All rights reserved.
433457Skarels  *
542798Sbostic  * %sccs.include.redist.c%
621138Sdist  */
721138Sdist 
89197Ssam #ifndef lint
921138Sdist char copyright[] =
1034772Sbostic "@(#) Copyright (c) 1983, 1988 Regents of the University of California.\n\
1121138Sdist  All rights reserved.\n";
1234772Sbostic #endif /* not lint */
136478Ssam 
1421138Sdist #ifndef lint
15*47697Sbostic static char sccsid[] = "@(#)implog.c	5.14 (Berkeley) 04/01/91";
1634772Sbostic #endif /* not lint */
1721138Sdist 
1837278Sbostic #include <sys/param.h>
1913600Ssam #include <sys/time.h>
2037278Sbostic #include <sys/signal.h>
2134037Skarels #include <sys/file.h>
226478Ssam #include <sys/stat.h>
236478Ssam #include <sys/socket.h>
249195Ssam 
2533455Skarels #include <net/if.h>
2633455Skarels 
279195Ssam #include <netinet/in.h>
2833455Skarels #define	IMPMESSAGES
296478Ssam #define	IMPLEADERS
309195Ssam #include <netimp/if_imp.h>
316478Ssam 
3237278Sbostic #include <sgtty.h>
3337278Sbostic #include <stdio.h>
3437278Sbostic #include "pathnames.h"
356478Ssam 
366478Ssam u_char	buf[1024];
376478Ssam int	showdata = 1;
386478Ssam int	showcontents = 0;
3927727Skarels int	rawheader = 0;
406478Ssam int	follow = 0;
4134037Skarels int	skip = 0;
42*47697Sbostic int	linkn = -1;
436478Ssam int	host = -1;
446478Ssam int	imp = -1;
456478Ssam int	packettype = -1;
466478Ssam extern	int errno;
476478Ssam int	log;
486478Ssam 
496478Ssam /*
506478Ssam  * Socket address, internet style, with
516478Ssam  * unused space taken by timestamp and packet
526478Ssam  * size.
536478Ssam  */
546478Ssam struct sockstamp {
556478Ssam 	short	sin_family;
566478Ssam 	u_short	sin_port;
576478Ssam 	struct	in_addr sin_addr;
586478Ssam 	time_t	sin_time;
596478Ssam 	int	sin_cc;
606478Ssam };
616478Ssam struct	sockstamp from;
626478Ssam 
main(argc,argv)636478Ssam main(argc, argv)
6437278Sbostic 	int argc;
6537278Sbostic 	char **argv;
666478Ssam {
6737278Sbostic 	extern int errno, optind;
6837278Sbostic 	extern char *optarg;
696478Ssam 	struct stat b;
7037278Sbostic 	off_t size, lseek();
7137278Sbostic 	char *logfile, *strerror();
7237278Sbostic 	int ch;
7337278Sbostic 	long hostfrom, impfrom;
746478Ssam 
7537278Sbostic 	while ((ch = getopt(argc, argv, "DFLcfh:i:l:rt:")) != EOF)
7637278Sbostic 		switch(ch) {
7737278Sbostic 		case 'D':
786478Ssam 			showdata = 0;
7937278Sbostic 			break;
8037278Sbostic 		case 'F':
8134037Skarels 			skip++;
8237278Sbostic 			/* FALLTHROUGH */
8337278Sbostic 		case 'f':
8434037Skarels 			follow++;
8537278Sbostic 			break;
8637278Sbostic 		case 'L':
87*47697Sbostic 			linkn = IMPLINK_IP;
8837278Sbostic 			break;
8937278Sbostic 		case 'c':
906478Ssam 			showcontents++;
9137278Sbostic 			break;
9237278Sbostic 		case 'h':
9337278Sbostic 			host = atoi(optarg);
9437278Sbostic 			break;
9537278Sbostic 		case 'i':
9637278Sbostic 			imp = atoi(optarg);
9737278Sbostic 			break;
9837278Sbostic 		case 'l':
99*47697Sbostic 			linkn = atoi(optarg);
10037278Sbostic 			break;
10137278Sbostic 		case 'r':
10227727Skarels 			rawheader++;
10337278Sbostic 			break;
10437278Sbostic 		case 't':
10537278Sbostic 			packettype = atoi(optarg);
10637278Sbostic 			break;
10737278Sbostic 		case '?':
10837278Sbostic 		default:
10937278Sbostic 			fprintf(stderr,
11037278Sbostic "usage: implog [-DFLcfr] [-h host] [-i imp] [-l link] [-t type] [logfile]\n");
11137278Sbostic 			exit(2);
11227727Skarels 		}
11337278Sbostic 	argc -= optind;
11437278Sbostic 	argv += optind;
11537278Sbostic 
11637278Sbostic 	logfile = argc ? *argv : _PATH_IMPLOG;
11737278Sbostic 	log = open(logfile, O_RDONLY, 0);
11837278Sbostic 	if (log < 0 || fstat(log, &b)) {
11937278Sbostic 		fprintf(stderr, "implog: %s: %s\n", logfile, strerror(errno));
1206478Ssam 		exit(1);
1216478Ssam 	}
1226478Ssam 	size = b.st_size;
12334037Skarels 	if (skip)
12437278Sbostic 		(void)lseek(log, size, L_SET);
1256478Ssam again:
1266478Ssam 	while (read(log, (char *)&from, sizeof(from)) == sizeof(from)) {
1276478Ssam 		if (from.sin_family == 0) {
1286478Ssam 			printf("restarted: %.24s\n", ctime(&from.sin_time));
1296478Ssam 			continue;
1306478Ssam 		}
13138002Skarels 		if (host >= 0 || imp >= 0) {
13238002Skarels 			long addr = ntohl(from.sin_addr.s_addr);
13322597Skarels 
13422597Skarels 			if (IN_CLASSA(addr)) {
13522597Skarels 				hostfrom = ((addr>>16) & 0xFF);
13622597Skarels 				impfrom = addr & 0xFF;
13722597Skarels 			} else if (IN_CLASSB(addr)) {
13822597Skarels 				hostfrom = ((addr>>8) & 0xFF);
13922597Skarels 				impfrom = addr & 0xFF;
14022597Skarels 			} else {
14122597Skarels 				hostfrom = ((addr>>4) & 0xF);
14222597Skarels 				impfrom = addr & 0xF;
14322597Skarels 			}
14422597Skarels 		}
14522597Skarels 		if (host >= 0 && hostfrom != host) {
14637278Sbostic 			(void)lseek(log, (long)from.sin_cc, L_INCR);
1476478Ssam 			continue;
1486478Ssam 		}
14922597Skarels 		if (imp >= 0 && impfrom != imp) {
15037278Sbostic 			(void)lseek(log, (long)from.sin_cc, L_INCR);
15122597Skarels 			continue;
1526478Ssam 		}
1536478Ssam 		process(log, &from);
1546478Ssam 	}
1556478Ssam 	while (follow) {
15637278Sbostic 		(void)fflush(stdout);
15737278Sbostic 		(void)sleep(5);
15837278Sbostic 		(void)fstat(log, &b);
1596478Ssam 		if (b.st_size > size) {
1606478Ssam 			size = b.st_size;
1616478Ssam 			goto again;
1626478Ssam 		}
1636478Ssam 	}
1646478Ssam }
1656478Ssam 
1666478Ssam int	impdata(), impbadleader(), impdown(), impnoop();
1676478Ssam int	imprfnm(), impincomplete(), imphostdead(), imphostunreach();
1686478Ssam int	impbaddata(), impreset(), impretry(), impnotify(), imptrying();
1696478Ssam int	impready(), impundef();
1706478Ssam 
1716478Ssam struct	messages {
1726478Ssam 	u_char	m_type;		/* type of message */
1736478Ssam 	int	(*m_func)();	/* routine to process message */
1746478Ssam } mtypes[] = {
1756478Ssam 	{ IMPTYPE_DATA,		impdata },
1766478Ssam 	{ IMPTYPE_BADLEADER,	impbadleader },
1776478Ssam 	{ IMPTYPE_DOWN,		impdown },
1786478Ssam 	{ IMPTYPE_NOOP,		impnoop },
1796478Ssam 	{ IMPTYPE_RFNM,		imprfnm },
1806478Ssam 	{ IMPTYPE_INCOMPLETE,	impincomplete },
1816478Ssam 	{ IMPTYPE_HOSTDEAD,	imphostdead },
1826478Ssam 	{ IMPTYPE_HOSTUNREACH,	imphostunreach },
1836478Ssam 	{ IMPTYPE_BADDATA,	impbaddata },
1846478Ssam 	{ IMPTYPE_RESET,	impreset },
1856478Ssam 	{ IMPTYPE_RETRY,	impretry },
1866478Ssam 	{ IMPTYPE_NOTIFY,	impnotify },
1876478Ssam 	{ IMPTYPE_TRYING,	imptrying },
1886478Ssam 	{ IMPTYPE_READY,	impready },
1896478Ssam 	{ -1,			impundef }
1906478Ssam };
1916478Ssam 
1926478Ssam /*
1936478Ssam  * Print a packet.
1946478Ssam  */
process(l,f)1956478Ssam process(l, f)
1966478Ssam 	int l;
1976478Ssam 	struct sockstamp *f;
1986478Ssam {
1996478Ssam 	register struct messages *mp;
2006478Ssam 	struct imp_leader *ip;
20127727Skarels 	int (*fn)();
2026478Ssam 
2036478Ssam 	if (read(l, (char *)buf, f->sin_cc) != f->sin_cc) {
20437278Sbostic 		perror("implog: read");
2056478Ssam 		return;
2066478Ssam 	}
2076478Ssam 	ip = (struct imp_leader *)buf;
20828904Skarels 	ip->il_imp = ntohs(ip->il_imp);
20927727Skarels 	if (ip->il_format != IMP_NFF)
21027727Skarels 		fn = impundef;
21127727Skarels 	else {
21233085Sbostic 		for (mp = mtypes; mp->m_type != (u_char)-1; mp++)
21327727Skarels 			if (mp->m_type == ip->il_mtype)
21427727Skarels 				break;
21527727Skarels 		fn = mp->m_func;
21627727Skarels 	}
21727727Skarels 	if (ip->il_mtype == IMPTYPE_DATA) {
218*47697Sbostic 		if (linkn >= 0 && ip->il_link != linkn)
2196478Ssam 			return;
2206478Ssam 		if (!showdata)
2216478Ssam 			return;
2226478Ssam 	}
22327727Skarels 	if (packettype >= 0 && ip->il_mtype != packettype)
2246478Ssam 		return;
2256478Ssam 	printf("%.24s: ", ctime(&f->sin_time));
22628904Skarels 	if (f->sin_cc < sizeof(struct control_leader))
22728904Skarels 		printf("(truncated header, %d bytes): ", f->sin_cc);
22827727Skarels 	(*fn)(ip, f->sin_cc);
22928904Skarels 	if (rawheader && fn != impundef) {
23028904Skarels 		putchar('\t');
23127727Skarels 		impundef(ip, f->sin_cc);
23228904Skarels 	}
2336478Ssam }
2346478Ssam 
impdata(ip,cc)2356478Ssam impdata(ip, cc)
2366478Ssam 	register struct imp_leader *ip;
23737278Sbostic 	int cc;
2386478Ssam {
23937278Sbostic 	printf("<DATA, source=%d/%u, link=", ip->il_host, (u_short)ip->il_imp);
2406478Ssam 	if (ip->il_link == IMPLINK_IP)
2416478Ssam 		printf("ip,");
2426478Ssam 	else
2436478Ssam 		printf("%d,", ip->il_link);
24437278Sbostic 	printf(" len=%u bytes>\n", ntohs((u_short)ip->il_length) >> 3);
2456478Ssam 	if (showcontents) {
2466478Ssam 		register u_char *cp = ((u_char *)ip) + sizeof(*ip);
2476478Ssam 		register int i;
2486478Ssam 
2496478Ssam 		i = (ntohs(ip->il_length) >> 3) - sizeof(struct imp_leader);
25037278Sbostic 		cc = MIN(i, cc);
2516478Ssam 		printf("data: (%d bytes)", cc);
2526478Ssam 		for (i = 0; i < cc; i++, cp++) {
2536478Ssam 			if (i % 25 == 0)
2546478Ssam 				printf("\n");
2556478Ssam 			printf("%02x ", *cp);
2566478Ssam 		}
2576478Ssam 		putchar('\n');
2586478Ssam 	}
2596478Ssam }
2606478Ssam 
2616478Ssam char *badleader[] = {
2626478Ssam 	"error flip-flop set",
2636478Ssam 	"message < 80 bits",
2646478Ssam 	"illegal type field",
2656478Ssam 	"opposite leader type"
2666478Ssam };
2676478Ssam 
26837278Sbostic /* ARGSUSED */
impbadleader(ip,cc)26937278Sbostic impbadleader(ip, cc)
2706478Ssam 	register struct imp_leader *ip;
27137278Sbostic 	int cc;
2726478Ssam {
2736478Ssam 	printf("bad leader: ");
2746478Ssam 	if (ip->il_subtype > IMPLEADER_OPPOSITE)
2756478Ssam 		printf("%x\n", ip->il_subtype);
2766478Ssam 	else
2776478Ssam 		printf("%s\n", badleader[ip->il_subtype]);
2786478Ssam }
2796478Ssam 
28037278Sbostic /* ARGSUSED */
impdown(ip,cc)28137278Sbostic impdown(ip, cc)
2826478Ssam 	register struct imp_leader *ip;
28337278Sbostic 	int cc;
2846478Ssam {
2856478Ssam 	int tdown, tbackup;
2866478Ssam 
28733455Skarels 	printf("imp going down %s", impmessage[ip->il_link & IMP_DMASK]);
28833455Skarels 	tdown = ((ip->il_link >> IMPDOWN_WHENSHIFT) & IMPDOWN_WHENMASK) *
28933455Skarels 	    IMPDOWN_WHENUNIT;
29033455Skarels 	if ((ip->il_link & IMP_DMASK) != IMPDOWN_GOING)
2916478Ssam 		printf(" in %d minutes", tdown);
29233455Skarels 	tbackup = ip->il_subtype * IMPDOWN_WHENUNIT;
2936478Ssam 	printf(": back up ");
2946478Ssam 	if (tbackup)
2956478Ssam 		printf("%d minutes\n", tbackup);
2966478Ssam 	else
2976478Ssam 		printf("immediately\n");
2986478Ssam }
2996478Ssam 
30037278Sbostic /* ARGSUSED */
impnoop(ip,cc)30137278Sbostic impnoop(ip, cc)
3026478Ssam 	register struct imp_leader *ip;
30337278Sbostic 	int cc;
3046478Ssam {
30537278Sbostic 	printf("noop: host %d, imp %u\n", ip->il_host, ip->il_imp);
3066478Ssam }
3076478Ssam 
30837278Sbostic /* ARGSUSED */
imprfnm(ip,cc)30937278Sbostic imprfnm(ip, cc)
3106478Ssam 	register struct imp_leader *ip;
31137278Sbostic 	int cc;
3126478Ssam {
31337278Sbostic 	printf("rfnm: htype=%x, source=%d/%u, link=",
3146478Ssam 		ip->il_htype, ip->il_host, ip->il_imp);
3156478Ssam 	if (ip->il_link == IMPLINK_IP)
3166478Ssam 		printf("ip,");
3176478Ssam 	else
31827727Skarels 		printf("%d,", ip->il_link);
3196478Ssam 	printf(" subtype=%x\n", ip->il_subtype);
3206478Ssam }
3216478Ssam 
3226478Ssam char *hostdead[] = {
3239195Ssam 	"#0",
3246478Ssam 	"ready-line negated",
3256478Ssam 	"tardy receiving messages",
3266478Ssam 	"ncc doesn't know host",
3276478Ssam 	"imp software won't allow messages",
3286478Ssam 	"host down for scheduled pm",
3296478Ssam 	"host down for hardware work",
3306478Ssam 	"host down for software work",
3316478Ssam 	"host down for emergency restart",
3326478Ssam 	"host down because of power outage",
3336478Ssam 	"host stopped at a breakpoint",
3346478Ssam 	"host down due to hardware failure",
3356478Ssam 	"host not scheduled to be up",
3369195Ssam 	"#13",
3379195Ssam 	"#14",
3386478Ssam 	"host in the process of coming up"
3396478Ssam };
3406478Ssam 
34137278Sbostic /* ARGSUSED */
imphostdead(ip,cc)34237278Sbostic imphostdead(ip, cc)
3436478Ssam 	register struct imp_leader *ip;
34437278Sbostic 	int cc;
3456478Ssam {
34637278Sbostic 	printf("host %u/%u dead: ", ip->il_host, ip->il_imp);
3476478Ssam 	if (ip->il_link & IMP_DMASK)
34833455Skarels 		printf("down %s, ", impmessage[ip->il_link & IMP_DMASK]);
3496478Ssam 	if (ip->il_subtype <= IMPHOST_COMINGUP)
3506478Ssam 		printf("%s\n", hostdead[ip->il_subtype]);
3516478Ssam 	else
3526478Ssam 		printf("subtype=%x\n", ip->il_subtype);
3536478Ssam }
3546478Ssam 
3556478Ssam char *hostunreach[] = {
3566478Ssam 	"destination imp can't be reached",
3576478Ssam 	"destination host isn't up",
3586478Ssam 	"host doesn't support long leader",
3596478Ssam 	"communication is prohibited"
3606478Ssam };
3616478Ssam 
36237278Sbostic /* ARGSUSED */
imphostunreach(ip,cc)36337278Sbostic imphostunreach(ip, cc)
3646478Ssam 	register struct imp_leader *ip;
36537278Sbostic 	int cc;
3666478Ssam {
36737278Sbostic 	printf("host %u/%u unreachable: ", ip->il_host, ip->il_imp);
3686478Ssam 	if (ip->il_subtype <= IMPREACH_PROHIBITED)
3696478Ssam 		printf("%s\n", hostunreach[ip->il_subtype]);
3706478Ssam 	else
3716478Ssam 		printf("subtype=%x\n", ip->il_subtype);
3726478Ssam }
3736478Ssam 
37437278Sbostic /* ARGSUSED */
impbaddata(ip,cc)37537278Sbostic impbaddata(ip, cc)
3766478Ssam 	register struct imp_leader *ip;
37737278Sbostic 	int cc;
3786478Ssam {
37937278Sbostic 	printf("error in data: htype=%x, source=%u/%u, link=",
3806478Ssam 		ip->il_htype, ip->il_host, ip->il_imp);
3816478Ssam 	if (ip->il_link == IMPLINK_IP)
3826478Ssam 		printf("ip, ");
3836478Ssam 	else
38427727Skarels 		printf("%d, ", ip->il_link);
3856478Ssam 	printf("subtype=%x\n", ip->il_subtype);
3866478Ssam }
3876478Ssam 
3886478Ssam char *incomplete[] = {
3896478Ssam 	"host didn't take data fast enough",
3906478Ssam 	"message was too long",
3916478Ssam 	"message transmission time > 15 seconds",
3926478Ssam 	"imp/circuit failure",
3936478Ssam 	"no resources within 15 seconds",
3946478Ssam 	"source imp i/o failure during receipt"
3956478Ssam };
3966478Ssam 
39737278Sbostic /* ARGSUSED */
impincomplete(ip,cc)39837278Sbostic impincomplete(ip, cc)
3996478Ssam 	register struct imp_leader *ip;
40037278Sbostic 	int cc;
4016478Ssam {
40237278Sbostic 	printf("incomplete: htype=%x, source=%u/%u, link=",
4036478Ssam 		ip->il_htype, ip->il_host, ip->il_imp);
4046478Ssam 	if (ip->il_link == IMPLINK_IP)
4056478Ssam 		printf("ip,");
4066478Ssam 	else
40727727Skarels 		printf("%d,", ip->il_link);
4086478Ssam 	if (ip->il_subtype <= IMPCOMPLETE_IMPIO)
4096478Ssam 		printf(" %s\n", incomplete[ip->il_subtype]);
4106478Ssam 	else
4116478Ssam 		printf(" subtype=%x\n", ip->il_subtype);
4126478Ssam }
4136478Ssam 
41437278Sbostic /* ARGSUSED */
41537278Sbostic impreset(ip, cc)
41637278Sbostic 	struct imp_leader *ip;
41737278Sbostic 	int cc;
4186478Ssam {
4196478Ssam 	printf("reset complete\n");
4206478Ssam }
4216478Ssam 
4226478Ssam char *retry[] = {
4236478Ssam 	"imp buffer wasn't available",
4246478Ssam 	"connection block unavailable"
4256478Ssam };
4266478Ssam 
42737278Sbostic /* ARGSUSED */
impretry(ip,cc)42837278Sbostic impretry(ip, cc)
4296478Ssam 	register struct imp_leader *ip;
43037278Sbostic 	int cc;
4316478Ssam {
4326478Ssam 	printf("refused, try again: ");
4336478Ssam 	if (ip->il_subtype <= IMPRETRY_BLOCK)
4346478Ssam 		printf("%s\n", retry[ip->il_subtype]);
4356478Ssam 	else
4366478Ssam 		printf("subtype=%x\n", ip->il_subtype);
4376478Ssam }
4386478Ssam 
4396478Ssam char *notify[] = {
4409195Ssam 	"#0",
4419195Ssam 	"#1",
4426478Ssam 	"connection not available",
4436478Ssam 	"reassembly space not available at destination",
4446478Ssam 	"message number not available",
4456478Ssam 	"transaction block for message not available"
4466478Ssam };
4476478Ssam 
44837278Sbostic /* ARGSUSED */
impnotify(ip,cc)44937278Sbostic impnotify(ip, cc)
4506478Ssam 	register struct imp_leader *ip;
45137278Sbostic 	int cc;
4526478Ssam {
4536478Ssam 	printf("refused, will notify: ");
4546478Ssam 	if (ip->il_subtype <= 5)
4556478Ssam 		printf("%s\n", notify[ip->il_subtype]);
4566478Ssam 	else
4576478Ssam 		printf("subtype=%x\n", ip->il_subtype);
4586478Ssam }
4596478Ssam 
46037278Sbostic /* ARGSUSED */
46137278Sbostic imptrying(ip, cc)
46237278Sbostic 	struct imp_leader *ip;
46337278Sbostic 	int cc;
4646478Ssam {
4656478Ssam 	printf("refused, still trying\n");
4666478Ssam }
4676478Ssam 
46837278Sbostic /* ARGSUSED */
46937278Sbostic impready(ip, cc)
47037278Sbostic 	struct imp_leader *ip;
47137278Sbostic 	int cc;
4726478Ssam {
4736478Ssam 	printf("ready\n");
4746478Ssam }
4756478Ssam 
47637278Sbostic /* ARGSUSED */
impundef(ip,cc)47737278Sbostic impundef(ip, cc)
4786478Ssam 	register struct imp_leader *ip;
47937278Sbostic 	int cc;
4806478Ssam {
4816478Ssam 	printf("<fmt=%x, net=%x, flags=%x, mtype=", ip->il_format,
4826478Ssam 		ip->il_network, ip->il_flags);
48337278Sbostic 	printf("%x, htype=%x,\n\t host=%d(x%x), imp=%u(x%x), link=",
48428904Skarels 		ip->il_mtype, ip->il_htype, ip->il_host, ip->il_host,
48528904Skarels 		ip->il_imp, ip->il_imp);
4866478Ssam 	if (ip->il_link == IMPLINK_IP)
4876478Ssam 		printf("ip,");
4886478Ssam 	else
48928904Skarels 		printf("%d (x%x),", ip->il_link, ip->il_link);
49028904Skarels 	printf(" subtype=%x", ip->il_subtype);
49137278Sbostic 	if (cc >= sizeof(struct imp_leader) && ip->il_length)
49237278Sbostic 		printf(" len=%u bytes", ntohs((u_short)ip->il_length) >> 3);
49328904Skarels 	printf(">\n");
4946478Ssam }
495