xref: /csrg-svn/old/implog/implog.c (revision 37278)
121138Sdist /*
234772Sbostic  * 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
634772Sbostic  * provided that the above copyright notice and this paragraph are
734772Sbostic  * duplicated in all such forms and that any documentation,
834772Sbostic  * advertising materials, and other materials related to such
934772Sbostic  * distribution and use acknowledge that the software was developed
1034772Sbostic  * by the University of California, Berkeley.  The name of the
1134772Sbostic  * University may not be used to endorse or promote products derived
1234772Sbostic  * from this software without specific prior written permission.
1334772Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1434772Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1534772Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1621138Sdist  */
1721138Sdist 
189197Ssam #ifndef lint
1921138Sdist char copyright[] =
2034772Sbostic "@(#) Copyright (c) 1983, 1988 Regents of the University of California.\n\
2121138Sdist  All rights reserved.\n";
2234772Sbostic #endif /* not lint */
236478Ssam 
2421138Sdist #ifndef lint
25*37278Sbostic static char sccsid[] = "@(#)implog.c	5.11 (Berkeley) 04/02/89";
2634772Sbostic #endif /* not lint */
2721138Sdist 
28*37278Sbostic #include <sys/param.h>
2913600Ssam #include <sys/time.h>
30*37278Sbostic #include <sys/signal.h>
3134037Skarels #include <sys/file.h>
326478Ssam #include <sys/stat.h>
336478Ssam #include <sys/socket.h>
349195Ssam 
3533455Skarels #include <net/if.h>
3633455Skarels 
379195Ssam #include <netinet/in.h>
3833455Skarels #define	IMPMESSAGES
396478Ssam #define	IMPLEADERS
409195Ssam #include <netimp/if_imp.h>
416478Ssam 
42*37278Sbostic #include <sgtty.h>
43*37278Sbostic #include <stdio.h>
44*37278Sbostic #include "pathnames.h"
456478Ssam 
466478Ssam u_char	buf[1024];
476478Ssam int	showdata = 1;
486478Ssam int	showcontents = 0;
4927727Skarels int	rawheader = 0;
506478Ssam int	follow = 0;
5134037Skarels int	skip = 0;
526478Ssam int	link = -1;
536478Ssam int	host = -1;
546478Ssam int	imp = -1;
556478Ssam int	packettype = -1;
566478Ssam extern	int errno;
576478Ssam int	log;
586478Ssam 
596478Ssam /*
606478Ssam  * Socket address, internet style, with
616478Ssam  * unused space taken by timestamp and packet
626478Ssam  * size.
636478Ssam  */
646478Ssam struct sockstamp {
656478Ssam 	short	sin_family;
666478Ssam 	u_short	sin_port;
676478Ssam 	struct	in_addr sin_addr;
686478Ssam 	time_t	sin_time;
696478Ssam 	int	sin_cc;
706478Ssam };
716478Ssam struct	sockstamp from;
726478Ssam 
736478Ssam main(argc, argv)
74*37278Sbostic 	int argc;
75*37278Sbostic 	char **argv;
766478Ssam {
77*37278Sbostic 	extern int errno, optind;
78*37278Sbostic 	extern char *optarg;
796478Ssam 	struct stat b;
80*37278Sbostic 	off_t size, lseek();
81*37278Sbostic 	char *logfile, *strerror();
82*37278Sbostic 	int ch;
83*37278Sbostic 	long hostfrom, impfrom;
846478Ssam 
85*37278Sbostic 	while ((ch = getopt(argc, argv, "DFLcfh:i:l:rt:")) != EOF)
86*37278Sbostic 		switch(ch) {
87*37278Sbostic 		case 'D':
886478Ssam 			showdata = 0;
89*37278Sbostic 			break;
90*37278Sbostic 		case 'F':
9134037Skarels 			skip++;
92*37278Sbostic 			/* FALLTHROUGH */
93*37278Sbostic 		case 'f':
9434037Skarels 			follow++;
95*37278Sbostic 			break;
96*37278Sbostic 		case 'L':
97*37278Sbostic 			link = IMPLINK_IP;
98*37278Sbostic 			break;
99*37278Sbostic 		case 'c':
1006478Ssam 			showcontents++;
101*37278Sbostic 			break;
102*37278Sbostic 		case 'h':
103*37278Sbostic 			host = atoi(optarg);
104*37278Sbostic 			break;
105*37278Sbostic 		case 'i':
106*37278Sbostic 			imp = atoi(optarg);
107*37278Sbostic 			break;
108*37278Sbostic 		case 'l':
109*37278Sbostic 			link = atoi(optarg);
110*37278Sbostic 			break;
111*37278Sbostic 		case 'r':
11227727Skarels 			rawheader++;
113*37278Sbostic 			break;
114*37278Sbostic 		case 't':
115*37278Sbostic 			packettype = atoi(optarg);
116*37278Sbostic 			break;
117*37278Sbostic 		case '?':
118*37278Sbostic 		default:
119*37278Sbostic 			fprintf(stderr,
120*37278Sbostic "usage: implog [-DFLcfr] [-h host] [-i imp] [-l link] [-t type] [logfile]\n");
121*37278Sbostic 			exit(2);
12227727Skarels 		}
123*37278Sbostic 	argc -= optind;
124*37278Sbostic 	argv += optind;
125*37278Sbostic 
126*37278Sbostic 	logfile = argc ? *argv : _PATH_IMPLOG;
127*37278Sbostic 	log = open(logfile, O_RDONLY, 0);
128*37278Sbostic 	if (log < 0 || fstat(log, &b)) {
129*37278Sbostic 		fprintf(stderr, "implog: %s: %s\n", logfile, strerror(errno));
1306478Ssam 		exit(1);
1316478Ssam 	}
1326478Ssam 	size = b.st_size;
13334037Skarels 	if (skip)
134*37278Sbostic 		(void)lseek(log, size, L_SET);
1356478Ssam again:
1366478Ssam 	while (read(log, (char *)&from, sizeof(from)) == sizeof(from)) {
1376478Ssam 		if (from.sin_family == 0) {
1386478Ssam 			printf("restarted: %.24s\n", ctime(&from.sin_time));
1396478Ssam 			continue;
1406478Ssam 		}
14122597Skarels 		if (host >= 0) {
14222597Skarels 			long addr = ntohs(from.sin_addr.s_addr);
14322597Skarels 
14422597Skarels 			if (IN_CLASSA(addr)) {
14522597Skarels 				hostfrom = ((addr>>16) & 0xFF);
14622597Skarels 				impfrom = addr & 0xFF;
14722597Skarels 			} else if (IN_CLASSB(addr)) {
14822597Skarels 				hostfrom = ((addr>>8) & 0xFF);
14922597Skarels 				impfrom = addr & 0xFF;
15022597Skarels 			} else {
15122597Skarels 				hostfrom = ((addr>>4) & 0xF);
15222597Skarels 				impfrom = addr & 0xF;
15322597Skarels 			}
15422597Skarels 		}
15522597Skarels 		if (host >= 0 && hostfrom != host) {
156*37278Sbostic 			(void)lseek(log, (long)from.sin_cc, L_INCR);
1576478Ssam 			continue;
1586478Ssam 		}
15922597Skarels 		if (imp >= 0 && impfrom != imp) {
160*37278Sbostic 			(void)lseek(log, (long)from.sin_cc, L_INCR);
16122597Skarels 			continue;
1626478Ssam 		}
1636478Ssam 		process(log, &from);
1646478Ssam 	}
1656478Ssam 	while (follow) {
166*37278Sbostic 		(void)fflush(stdout);
167*37278Sbostic 		(void)sleep(5);
168*37278Sbostic 		(void)fstat(log, &b);
1696478Ssam 		if (b.st_size > size) {
1706478Ssam 			size = b.st_size;
1716478Ssam 			goto again;
1726478Ssam 		}
1736478Ssam 	}
1746478Ssam }
1756478Ssam 
1766478Ssam int	impdata(), impbadleader(), impdown(), impnoop();
1776478Ssam int	imprfnm(), impincomplete(), imphostdead(), imphostunreach();
1786478Ssam int	impbaddata(), impreset(), impretry(), impnotify(), imptrying();
1796478Ssam int	impready(), impundef();
1806478Ssam 
1816478Ssam struct	messages {
1826478Ssam 	u_char	m_type;		/* type of message */
1836478Ssam 	int	(*m_func)();	/* routine to process message */
1846478Ssam } mtypes[] = {
1856478Ssam 	{ IMPTYPE_DATA,		impdata },
1866478Ssam 	{ IMPTYPE_BADLEADER,	impbadleader },
1876478Ssam 	{ IMPTYPE_DOWN,		impdown },
1886478Ssam 	{ IMPTYPE_NOOP,		impnoop },
1896478Ssam 	{ IMPTYPE_RFNM,		imprfnm },
1906478Ssam 	{ IMPTYPE_INCOMPLETE,	impincomplete },
1916478Ssam 	{ IMPTYPE_HOSTDEAD,	imphostdead },
1926478Ssam 	{ IMPTYPE_HOSTUNREACH,	imphostunreach },
1936478Ssam 	{ IMPTYPE_BADDATA,	impbaddata },
1946478Ssam 	{ IMPTYPE_RESET,	impreset },
1956478Ssam 	{ IMPTYPE_RETRY,	impretry },
1966478Ssam 	{ IMPTYPE_NOTIFY,	impnotify },
1976478Ssam 	{ IMPTYPE_TRYING,	imptrying },
1986478Ssam 	{ IMPTYPE_READY,	impready },
1996478Ssam 	{ -1,			impundef }
2006478Ssam };
2016478Ssam 
2026478Ssam /*
2036478Ssam  * Print a packet.
2046478Ssam  */
2056478Ssam process(l, f)
2066478Ssam 	int l;
2076478Ssam 	struct sockstamp *f;
2086478Ssam {
2096478Ssam 	register struct messages *mp;
2106478Ssam 	struct imp_leader *ip;
21127727Skarels 	int (*fn)();
2126478Ssam 
2136478Ssam 	if (read(l, (char *)buf, f->sin_cc) != f->sin_cc) {
214*37278Sbostic 		perror("implog: read");
2156478Ssam 		return;
2166478Ssam 	}
2176478Ssam 	ip = (struct imp_leader *)buf;
21828904Skarels 	ip->il_imp = ntohs(ip->il_imp);
21927727Skarels 	if (ip->il_format != IMP_NFF)
22027727Skarels 		fn = impundef;
22127727Skarels 	else {
22233085Sbostic 		for (mp = mtypes; mp->m_type != (u_char)-1; mp++)
22327727Skarels 			if (mp->m_type == ip->il_mtype)
22427727Skarels 				break;
22527727Skarels 		fn = mp->m_func;
22627727Skarels 	}
22727727Skarels 	if (ip->il_mtype == IMPTYPE_DATA) {
2286478Ssam 		if (link >= 0 && ip->il_link != link)
2296478Ssam 			return;
2306478Ssam 		if (!showdata)
2316478Ssam 			return;
2326478Ssam 	}
23327727Skarels 	if (packettype >= 0 && ip->il_mtype != packettype)
2346478Ssam 		return;
2356478Ssam 	printf("%.24s: ", ctime(&f->sin_time));
23628904Skarels 	if (f->sin_cc < sizeof(struct control_leader))
23728904Skarels 		printf("(truncated header, %d bytes): ", f->sin_cc);
23827727Skarels 	(*fn)(ip, f->sin_cc);
23928904Skarels 	if (rawheader && fn != impundef) {
24028904Skarels 		putchar('\t');
24127727Skarels 		impundef(ip, f->sin_cc);
24228904Skarels 	}
2436478Ssam }
2446478Ssam 
2456478Ssam impdata(ip, cc)
2466478Ssam 	register struct imp_leader *ip;
247*37278Sbostic 	int cc;
2486478Ssam {
249*37278Sbostic 	printf("<DATA, source=%d/%u, link=", ip->il_host, (u_short)ip->il_imp);
2506478Ssam 	if (ip->il_link == IMPLINK_IP)
2516478Ssam 		printf("ip,");
2526478Ssam 	else
2536478Ssam 		printf("%d,", ip->il_link);
254*37278Sbostic 	printf(" len=%u bytes>\n", ntohs((u_short)ip->il_length) >> 3);
2556478Ssam 	if (showcontents) {
2566478Ssam 		register u_char *cp = ((u_char *)ip) + sizeof(*ip);
2576478Ssam 		register int i;
2586478Ssam 
2596478Ssam 		i = (ntohs(ip->il_length) >> 3) - sizeof(struct imp_leader);
260*37278Sbostic 		cc = MIN(i, cc);
2616478Ssam 		printf("data: (%d bytes)", cc);
2626478Ssam 		for (i = 0; i < cc; i++, cp++) {
2636478Ssam 			if (i % 25 == 0)
2646478Ssam 				printf("\n");
2656478Ssam 			printf("%02x ", *cp);
2666478Ssam 		}
2676478Ssam 		putchar('\n');
2686478Ssam 	}
2696478Ssam }
2706478Ssam 
2716478Ssam char *badleader[] = {
2726478Ssam 	"error flip-flop set",
2736478Ssam 	"message < 80 bits",
2746478Ssam 	"illegal type field",
2756478Ssam 	"opposite leader type"
2766478Ssam };
2776478Ssam 
278*37278Sbostic /* ARGSUSED */
279*37278Sbostic impbadleader(ip, cc)
2806478Ssam 	register struct imp_leader *ip;
281*37278Sbostic 	int cc;
2826478Ssam {
2836478Ssam 	printf("bad leader: ");
2846478Ssam 	if (ip->il_subtype > IMPLEADER_OPPOSITE)
2856478Ssam 		printf("%x\n", ip->il_subtype);
2866478Ssam 	else
2876478Ssam 		printf("%s\n", badleader[ip->il_subtype]);
2886478Ssam }
2896478Ssam 
290*37278Sbostic /* ARGSUSED */
291*37278Sbostic impdown(ip, cc)
2926478Ssam 	register struct imp_leader *ip;
293*37278Sbostic 	int cc;
2946478Ssam {
2956478Ssam 	int tdown, tbackup;
2966478Ssam 
29733455Skarels 	printf("imp going down %s", impmessage[ip->il_link & IMP_DMASK]);
29833455Skarels 	tdown = ((ip->il_link >> IMPDOWN_WHENSHIFT) & IMPDOWN_WHENMASK) *
29933455Skarels 	    IMPDOWN_WHENUNIT;
30033455Skarels 	if ((ip->il_link & IMP_DMASK) != IMPDOWN_GOING)
3016478Ssam 		printf(" in %d minutes", tdown);
30233455Skarels 	tbackup = ip->il_subtype * IMPDOWN_WHENUNIT;
3036478Ssam 	printf(": back up ");
3046478Ssam 	if (tbackup)
3056478Ssam 		printf("%d minutes\n", tbackup);
3066478Ssam 	else
3076478Ssam 		printf("immediately\n");
3086478Ssam }
3096478Ssam 
310*37278Sbostic /* ARGSUSED */
311*37278Sbostic impnoop(ip, cc)
3126478Ssam 	register struct imp_leader *ip;
313*37278Sbostic 	int cc;
3146478Ssam {
315*37278Sbostic 	printf("noop: host %d, imp %u\n", ip->il_host, ip->il_imp);
3166478Ssam }
3176478Ssam 
318*37278Sbostic /* ARGSUSED */
319*37278Sbostic imprfnm(ip, cc)
3206478Ssam 	register struct imp_leader *ip;
321*37278Sbostic 	int cc;
3226478Ssam {
323*37278Sbostic 	printf("rfnm: htype=%x, source=%d/%u, 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 
351*37278Sbostic /* ARGSUSED */
352*37278Sbostic imphostdead(ip, cc)
3536478Ssam 	register struct imp_leader *ip;
354*37278Sbostic 	int cc;
3556478Ssam {
356*37278Sbostic 	printf("host %u/%u dead: ", ip->il_host, ip->il_imp);
3576478Ssam 	if (ip->il_link & IMP_DMASK)
35833455Skarels 		printf("down %s, ", impmessage[ip->il_link & IMP_DMASK]);
3596478Ssam 	if (ip->il_subtype <= IMPHOST_COMINGUP)
3606478Ssam 		printf("%s\n", hostdead[ip->il_subtype]);
3616478Ssam 	else
3626478Ssam 		printf("subtype=%x\n", ip->il_subtype);
3636478Ssam }
3646478Ssam 
3656478Ssam char *hostunreach[] = {
3666478Ssam 	"destination imp can't be reached",
3676478Ssam 	"destination host isn't up",
3686478Ssam 	"host doesn't support long leader",
3696478Ssam 	"communication is prohibited"
3706478Ssam };
3716478Ssam 
372*37278Sbostic /* ARGSUSED */
373*37278Sbostic imphostunreach(ip, cc)
3746478Ssam 	register struct imp_leader *ip;
375*37278Sbostic 	int cc;
3766478Ssam {
377*37278Sbostic 	printf("host %u/%u unreachable: ", ip->il_host, ip->il_imp);
3786478Ssam 	if (ip->il_subtype <= IMPREACH_PROHIBITED)
3796478Ssam 		printf("%s\n", hostunreach[ip->il_subtype]);
3806478Ssam 	else
3816478Ssam 		printf("subtype=%x\n", ip->il_subtype);
3826478Ssam }
3836478Ssam 
384*37278Sbostic /* ARGSUSED */
385*37278Sbostic impbaddata(ip, cc)
3866478Ssam 	register struct imp_leader *ip;
387*37278Sbostic 	int cc;
3886478Ssam {
389*37278Sbostic 	printf("error in data: htype=%x, source=%u/%u, link=",
3906478Ssam 		ip->il_htype, ip->il_host, ip->il_imp);
3916478Ssam 	if (ip->il_link == IMPLINK_IP)
3926478Ssam 		printf("ip, ");
3936478Ssam 	else
39427727Skarels 		printf("%d, ", ip->il_link);
3956478Ssam 	printf("subtype=%x\n", ip->il_subtype);
3966478Ssam }
3976478Ssam 
3986478Ssam char *incomplete[] = {
3996478Ssam 	"host didn't take data fast enough",
4006478Ssam 	"message was too long",
4016478Ssam 	"message transmission time > 15 seconds",
4026478Ssam 	"imp/circuit failure",
4036478Ssam 	"no resources within 15 seconds",
4046478Ssam 	"source imp i/o failure during receipt"
4056478Ssam };
4066478Ssam 
407*37278Sbostic /* ARGSUSED */
408*37278Sbostic impincomplete(ip, cc)
4096478Ssam 	register struct imp_leader *ip;
410*37278Sbostic 	int cc;
4116478Ssam {
412*37278Sbostic 	printf("incomplete: htype=%x, source=%u/%u, link=",
4136478Ssam 		ip->il_htype, ip->il_host, ip->il_imp);
4146478Ssam 	if (ip->il_link == IMPLINK_IP)
4156478Ssam 		printf("ip,");
4166478Ssam 	else
41727727Skarels 		printf("%d,", ip->il_link);
4186478Ssam 	if (ip->il_subtype <= IMPCOMPLETE_IMPIO)
4196478Ssam 		printf(" %s\n", incomplete[ip->il_subtype]);
4206478Ssam 	else
4216478Ssam 		printf(" subtype=%x\n", ip->il_subtype);
4226478Ssam }
4236478Ssam 
424*37278Sbostic /* ARGSUSED */
425*37278Sbostic impreset(ip, cc)
426*37278Sbostic 	struct imp_leader *ip;
427*37278Sbostic 	int cc;
4286478Ssam {
4296478Ssam 	printf("reset complete\n");
4306478Ssam }
4316478Ssam 
4326478Ssam char *retry[] = {
4336478Ssam 	"imp buffer wasn't available",
4346478Ssam 	"connection block unavailable"
4356478Ssam };
4366478Ssam 
437*37278Sbostic /* ARGSUSED */
438*37278Sbostic impretry(ip, cc)
4396478Ssam 	register struct imp_leader *ip;
440*37278Sbostic 	int cc;
4416478Ssam {
4426478Ssam 	printf("refused, try again: ");
4436478Ssam 	if (ip->il_subtype <= IMPRETRY_BLOCK)
4446478Ssam 		printf("%s\n", retry[ip->il_subtype]);
4456478Ssam 	else
4466478Ssam 		printf("subtype=%x\n", ip->il_subtype);
4476478Ssam }
4486478Ssam 
4496478Ssam char *notify[] = {
4509195Ssam 	"#0",
4519195Ssam 	"#1",
4526478Ssam 	"connection not available",
4536478Ssam 	"reassembly space not available at destination",
4546478Ssam 	"message number not available",
4556478Ssam 	"transaction block for message not available"
4566478Ssam };
4576478Ssam 
458*37278Sbostic /* ARGSUSED */
459*37278Sbostic impnotify(ip, cc)
4606478Ssam 	register struct imp_leader *ip;
461*37278Sbostic 	int cc;
4626478Ssam {
4636478Ssam 	printf("refused, will notify: ");
4646478Ssam 	if (ip->il_subtype <= 5)
4656478Ssam 		printf("%s\n", notify[ip->il_subtype]);
4666478Ssam 	else
4676478Ssam 		printf("subtype=%x\n", ip->il_subtype);
4686478Ssam }
4696478Ssam 
470*37278Sbostic /* ARGSUSED */
471*37278Sbostic imptrying(ip, cc)
472*37278Sbostic 	struct imp_leader *ip;
473*37278Sbostic 	int cc;
4746478Ssam {
4756478Ssam 	printf("refused, still trying\n");
4766478Ssam }
4776478Ssam 
478*37278Sbostic /* ARGSUSED */
479*37278Sbostic impready(ip, cc)
480*37278Sbostic 	struct imp_leader *ip;
481*37278Sbostic 	int cc;
4826478Ssam {
4836478Ssam 	printf("ready\n");
4846478Ssam }
4856478Ssam 
486*37278Sbostic /* ARGSUSED */
487*37278Sbostic impundef(ip, cc)
4886478Ssam 	register struct imp_leader *ip;
489*37278Sbostic 	int cc;
4906478Ssam {
4916478Ssam 	printf("<fmt=%x, net=%x, flags=%x, mtype=", ip->il_format,
4926478Ssam 		ip->il_network, ip->il_flags);
493*37278Sbostic 	printf("%x, htype=%x,\n\t host=%d(x%x), imp=%u(x%x), link=",
49428904Skarels 		ip->il_mtype, ip->il_htype, ip->il_host, ip->il_host,
49528904Skarels 		ip->il_imp, ip->il_imp);
4966478Ssam 	if (ip->il_link == IMPLINK_IP)
4976478Ssam 		printf("ip,");
4986478Ssam 	else
49928904Skarels 		printf("%d (x%x),", ip->il_link, ip->il_link);
50028904Skarels 	printf(" subtype=%x", ip->il_subtype);
501*37278Sbostic 	if (cc >= sizeof(struct imp_leader) && ip->il_length)
502*37278Sbostic 		printf(" len=%u bytes", ntohs((u_short)ip->il_length) >> 3);
50328904Skarels 	printf(">\n");
5046478Ssam }
505