xref: /csrg-svn/sbin/routed/trace.c (revision 10245)
19022Ssam #ifndef lint
2*10245Ssam static char sccsid[] = "@(#)trace.c	4.2 01/11/83";
39022Ssam #endif
49022Ssam 
59022Ssam /*
69022Ssam  * Routing Table Management Daemon
79022Ssam  */
89022Ssam #define	RIPCMDS
9*10245Ssam #include "defs.h"
109022Ssam 
119022Ssam #define	NRECORDS	50		/* size of circular trace buffer */
129022Ssam #ifdef DEBUG
139022Ssam FILE	*ftrace = stdout;
149022Ssam int	tracing = 1;
159022Ssam #endif
169022Ssam 
179022Ssam traceinit(ifp)
189022Ssam 	register struct interface *ifp;
199022Ssam {
209022Ssam 
219022Ssam 	if (iftraceinit(ifp, &ifp->int_input) &&
229022Ssam 	    iftraceinit(ifp, &ifp->int_output))
239022Ssam 		return;
249022Ssam 	tracing = 0;
259022Ssam 	fprintf(stderr, "traceinit: can't init %s\n", ifp->int_name);
269022Ssam }
279022Ssam 
289022Ssam static
299022Ssam iftraceinit(ifp, ifd)
309022Ssam 	struct interface *ifp;
319022Ssam 	register struct ifdebug *ifd;
329022Ssam {
339022Ssam 	register struct iftrace *t;
349022Ssam 
359022Ssam 	ifd->ifd_records =
369022Ssam 	  (struct iftrace *)malloc(NRECORDS * sizeof (struct iftrace));
379022Ssam 	if (ifd->ifd_records == 0)
389022Ssam 		return (0);
399022Ssam 	ifd->ifd_front = ifd->ifd_records;
409022Ssam 	for (t = ifd->ifd_records; t < ifd->ifd_records + NRECORDS; t++) {
419022Ssam 		t->ift_size = 0;
429022Ssam 		t->ift_packet = 0;
439022Ssam 	}
449022Ssam 	ifd->ifd_if = ifp;
459022Ssam 	return (1);
469022Ssam }
479022Ssam 
489022Ssam traceon(file)
499022Ssam 	char *file;
509022Ssam {
519022Ssam 
529022Ssam 	if (ftrace != NULL)
539022Ssam 		return;
549022Ssam 	ftrace = fopen(file, "a");
559022Ssam 	if (ftrace == NULL)
569022Ssam 		return;
579022Ssam 	dup2(fileno(ftrace), 1);
589022Ssam 	dup2(fileno(ftrace), 2);
599022Ssam 	tracing = 1;
609022Ssam }
619022Ssam 
629022Ssam traceoff()
639022Ssam {
649022Ssam 	if (!tracing)
659022Ssam 		return;
669022Ssam 	if (ftrace != NULL)
679022Ssam 		fclose(ftrace);
689022Ssam 	ftrace = NULL;
699022Ssam 	tracing = 0;
709022Ssam }
719022Ssam 
729022Ssam trace(ifd, who, p, len, m)
739022Ssam 	register struct ifdebug *ifd;
749022Ssam 	struct sockaddr *who;
759022Ssam 	char *p;
769022Ssam 	int len, m;
779022Ssam {
789022Ssam 	register struct iftrace *t;
799022Ssam 
809022Ssam 	if (ifd->ifd_records == 0)
819022Ssam 		return;
829022Ssam 	t = ifd->ifd_front++;
839022Ssam 	if (ifd->ifd_front >= ifd->ifd_records + NRECORDS)
849022Ssam 		ifd->ifd_front = ifd->ifd_records;
859022Ssam 	if (t->ift_size > 0 && t->ift_packet)
869022Ssam 		free(t->ift_packet);
879022Ssam 	t->ift_packet = 0;
889022Ssam 	t->ift_stamp = time(0);
899022Ssam 	t->ift_who = *who;
909022Ssam 	if (len > 0) {
919022Ssam 		t->ift_packet = malloc(len);
929022Ssam 		if (t->ift_packet)
939022Ssam 			bcopy(p, t->ift_packet, len);
949022Ssam 		else
959022Ssam 			len = 0;
969022Ssam 	}
979022Ssam 	t->ift_size = len;
989022Ssam 	t->ift_metric = m;
999022Ssam }
1009022Ssam 
1019022Ssam traceaction(fd, action, rt)
1029022Ssam 	FILE *fd;
1039022Ssam 	char *action;
1049022Ssam 	struct rt_entry *rt;
1059022Ssam {
1069022Ssam 	struct sockaddr_in *dst, *gate;
1079022Ssam 	static struct bits {
1089022Ssam 		int	t_bits;
1099022Ssam 		char	*t_name;
1109022Ssam 	} flagbits[] = {
1119022Ssam 		{ RTF_UP,	"UP" },
1129022Ssam 		{ RTF_GATEWAY,	"GATEWAY" },
1139022Ssam 		{ RTF_HOST,	"HOST" },
1149022Ssam 		{ 0 }
1159022Ssam 	}, statebits[] = {
1169022Ssam 		{ RTS_PASSIVE,	"PASSIVE" },
1179022Ssam 		{ RTS_REMOTE,	"REMOTE" },
1189022Ssam 		{ RTS_INTERFACE,"INTERFACE" },
1199022Ssam 		{ RTS_CHANGED,	"CHANGED" },
1209022Ssam 		{ 0 }
1219022Ssam 	};
1229022Ssam 	register struct bits *p;
1239022Ssam 	register int first;
1249022Ssam 	char *cp;
1259022Ssam 	struct interface *ifp;
1269022Ssam 
1279022Ssam 	if (fd == NULL)
1289022Ssam 		return;
1299022Ssam 	fprintf(fd, "%s ", action);
1309022Ssam 	dst = (struct sockaddr_in *)&rt->rt_dst;
1319022Ssam 	gate = (struct sockaddr_in *)&rt->rt_router;
1329022Ssam 	fprintf(fd, "dst %x, router %x, metric %d, flags", dst->sin_addr,
1339022Ssam 		gate->sin_addr, rt->rt_metric);
1349022Ssam 	cp = " %s";
1359022Ssam 	for (first = 1, p = flagbits; p->t_bits > 0; p++) {
1369022Ssam 		if ((rt->rt_flags & p->t_bits) == 0)
1379022Ssam 			continue;
1389022Ssam 		fprintf(fd, cp, p->t_name);
1399022Ssam 		if (first) {
1409022Ssam 			cp = "|%s";
1419022Ssam 			first = 0;
1429022Ssam 		}
1439022Ssam 	}
1449022Ssam 	fprintf(fd, " state");
1459022Ssam 	cp = " %s";
1469022Ssam 	for (first = 1, p = statebits; p->t_bits > 0; p++) {
1479022Ssam 		if ((rt->rt_state & p->t_bits) == 0)
1489022Ssam 			continue;
1499022Ssam 		fprintf(fd, cp, p->t_name);
1509022Ssam 		if (first) {
1519022Ssam 			cp = "|%s";
1529022Ssam 			first = 0;
1539022Ssam 		}
1549022Ssam 	}
1559022Ssam 	putc('\n', fd);
1569022Ssam 	if ((rt->rt_state & RTS_PASSIVE) == 0 && rt->rt_ifp)
1579022Ssam 		dumpif(fd, rt->rt_ifp);
1589022Ssam 	fflush(fd);
1599022Ssam }
1609022Ssam 
1619022Ssam dumpif(fd, ifp)
1629022Ssam 	register struct interface *ifp;
1639022Ssam {
1649022Ssam 	register struct ifdebug *ifd;
1659022Ssam 
1669022Ssam 	fprintf(fd, "*** Packet history for interface %s ***\n",
1679022Ssam 		ifp->int_name);
1689022Ssam 	dumptrace(fd, "to", &ifp->int_output);
1699022Ssam 	dumptrace(fd, "from", &ifp->int_output);
1709022Ssam 	fprintf(fd, "*** end packet history ***\n");
1719022Ssam }
1729022Ssam 
1739022Ssam dumptrace(fd, dir, ifd)
1749022Ssam 	FILE *fd;
1759022Ssam 	char *dir;
1769022Ssam 	register struct ifdebug *ifd;
1779022Ssam {
1789022Ssam 	register struct iftrace *t;
1799022Ssam 	char *cp = !strcmp(dir, "to") ? "Output" : "Input";
1809022Ssam 
1819022Ssam 	if (ifd->ifd_front == ifd->ifd_records &&
1829022Ssam 	    ifd->ifd_front->ift_size == 0) {
1839022Ssam 		fprintf(fd, "%s: no packets.\n", cp);
1849022Ssam 		return;
1859022Ssam 	}
1869022Ssam 	fprintf(fd, "%s trace:\n", cp);
1879022Ssam 	for (t = ifd->ifd_front; t <= ifd->ifd_records + NRECORDS; t++) {
1889022Ssam 		if (t->ift_size == 0)
1899022Ssam 			continue;
1909022Ssam 		fprintf(fd, "%.24s: metric=%d\n", ctime(&t->ift_stamp),
1919022Ssam 			t->ift_metric);
1929022Ssam 		dumppacket(fd, dir, &t->ift_who, t->ift_packet, t->ift_size);
1939022Ssam 	}
1949022Ssam 	for (t = ifd->ifd_records; t < ifd->ifd_front; t++) {
1959022Ssam 		if (t->ift_size == 0)
1969022Ssam 			continue;
1979022Ssam 		fprintf(fd, "%.24s: metric=%d\n", ctime(&t->ift_stamp),
1989022Ssam 			t->ift_metric);
1999022Ssam 		dumppacket(fd, dir, &t->ift_who, t->ift_packet, t->ift_size);
2009022Ssam 	}
2019022Ssam }
2029022Ssam 
2039022Ssam dumppacket(fd, dir, who, cp, size)
2049022Ssam 	FILE *fd;
2059022Ssam 	struct sockaddr_in *who;		/* should be sockaddr */
2069022Ssam 	char *dir, *cp;
2079022Ssam 	register int size;
2089022Ssam {
2099022Ssam 	register struct rip *msg = (struct rip *)cp;
2109022Ssam 	register struct netinfo *n;
2119022Ssam 
2129022Ssam 	if (msg->rip_cmd && msg->rip_cmd < RIPCMD_MAX)
2139022Ssam 		fprintf(fd, "%s %s %x.%d", ripcmds[msg->rip_cmd],
2149022Ssam 			dir, who->sin_addr, ntohs(who->sin_port));
2159022Ssam 	else {
2169022Ssam 		fprintf(fd, "Bad cmd 0x%x %s %x.%d\n", msg->rip_cmd,
2179022Ssam 			dir, who->sin_addr, ntohs(who->sin_port));
2189022Ssam 		fprintf(fd, "size=%d cp=%x packet=%x\n", size, cp, packet);
2199022Ssam 		return;
2209022Ssam 	}
2219022Ssam 	switch (msg->rip_cmd) {
2229022Ssam 
2239022Ssam 	case RIPCMD_REQUEST:
2249022Ssam 	case RIPCMD_RESPONSE:
2259022Ssam 		fprintf(fd, ":\n");
2269022Ssam 		size -= 4 * sizeof (char);
2279022Ssam 		n = msg->rip_nets;
2289022Ssam 		for (; size > 0; n++, size -= sizeof (struct netinfo)) {
2299022Ssam 			if (size < sizeof (struct netinfo))
2309022Ssam 				break;
2319022Ssam 			fprintf(fd, "\tdst %x metric %d\n",
2329022Ssam 				((struct sockaddr_in *)&n->rip_dst)->sin_addr,
2339022Ssam 				n->rip_metric);
2349022Ssam 		}
2359022Ssam 		break;
2369022Ssam 
2379022Ssam 	case RIPCMD_TRACEON:
2389022Ssam 		fprintf(fd, ", file=%*s\n", size, msg->rip_tracefile);
2399022Ssam 		break;
2409022Ssam 
2419022Ssam 	case RIPCMD_TRACEOFF:
2429022Ssam 		fprintf(fd, "\n");
2439022Ssam 		break;
2449022Ssam 	}
2459022Ssam }
246