xref: /csrg-svn/sbin/routed/trace.c (revision 9022)
1*9022Ssam #ifndef lint
2*9022Ssam static char sccsid[] = "@(#)trace.c	4.1 11/02/82";
3*9022Ssam #endif
4*9022Ssam 
5*9022Ssam /*
6*9022Ssam  * Routing Table Management Daemon
7*9022Ssam  */
8*9022Ssam #define	RIPCMDS
9*9022Ssam #include "router.h"
10*9022Ssam 
11*9022Ssam #define	NRECORDS	50		/* size of circular trace buffer */
12*9022Ssam #ifdef DEBUG
13*9022Ssam FILE	*ftrace = stdout;
14*9022Ssam int	tracing = 1;
15*9022Ssam #endif
16*9022Ssam 
17*9022Ssam traceinit(ifp)
18*9022Ssam 	register struct interface *ifp;
19*9022Ssam {
20*9022Ssam 
21*9022Ssam 	if (iftraceinit(ifp, &ifp->int_input) &&
22*9022Ssam 	    iftraceinit(ifp, &ifp->int_output))
23*9022Ssam 		return;
24*9022Ssam 	tracing = 0;
25*9022Ssam 	fprintf(stderr, "traceinit: can't init %s\n", ifp->int_name);
26*9022Ssam }
27*9022Ssam 
28*9022Ssam static
29*9022Ssam iftraceinit(ifp, ifd)
30*9022Ssam 	struct interface *ifp;
31*9022Ssam 	register struct ifdebug *ifd;
32*9022Ssam {
33*9022Ssam 	register struct iftrace *t;
34*9022Ssam 
35*9022Ssam 	ifd->ifd_records =
36*9022Ssam 	  (struct iftrace *)malloc(NRECORDS * sizeof (struct iftrace));
37*9022Ssam 	if (ifd->ifd_records == 0)
38*9022Ssam 		return (0);
39*9022Ssam 	ifd->ifd_front = ifd->ifd_records;
40*9022Ssam 	for (t = ifd->ifd_records; t < ifd->ifd_records + NRECORDS; t++) {
41*9022Ssam 		t->ift_size = 0;
42*9022Ssam 		t->ift_packet = 0;
43*9022Ssam 	}
44*9022Ssam 	ifd->ifd_if = ifp;
45*9022Ssam 	return (1);
46*9022Ssam }
47*9022Ssam 
48*9022Ssam traceon(file)
49*9022Ssam 	char *file;
50*9022Ssam {
51*9022Ssam 
52*9022Ssam 	if (ftrace != NULL)
53*9022Ssam 		return;
54*9022Ssam 	ftrace = fopen(file, "a");
55*9022Ssam 	if (ftrace == NULL)
56*9022Ssam 		return;
57*9022Ssam 	dup2(fileno(ftrace), 1);
58*9022Ssam 	dup2(fileno(ftrace), 2);
59*9022Ssam 	tracing = 1;
60*9022Ssam }
61*9022Ssam 
62*9022Ssam traceoff()
63*9022Ssam {
64*9022Ssam 	if (!tracing)
65*9022Ssam 		return;
66*9022Ssam 	if (ftrace != NULL)
67*9022Ssam 		fclose(ftrace);
68*9022Ssam 	ftrace = NULL;
69*9022Ssam 	tracing = 0;
70*9022Ssam }
71*9022Ssam 
72*9022Ssam trace(ifd, who, p, len, m)
73*9022Ssam 	register struct ifdebug *ifd;
74*9022Ssam 	struct sockaddr *who;
75*9022Ssam 	char *p;
76*9022Ssam 	int len, m;
77*9022Ssam {
78*9022Ssam 	register struct iftrace *t;
79*9022Ssam 
80*9022Ssam 	if (ifd->ifd_records == 0)
81*9022Ssam 		return;
82*9022Ssam 	t = ifd->ifd_front++;
83*9022Ssam 	if (ifd->ifd_front >= ifd->ifd_records + NRECORDS)
84*9022Ssam 		ifd->ifd_front = ifd->ifd_records;
85*9022Ssam 	if (t->ift_size > 0 && t->ift_packet)
86*9022Ssam 		free(t->ift_packet);
87*9022Ssam 	t->ift_packet = 0;
88*9022Ssam 	t->ift_stamp = time(0);
89*9022Ssam 	t->ift_who = *who;
90*9022Ssam 	if (len > 0) {
91*9022Ssam 		t->ift_packet = malloc(len);
92*9022Ssam 		if (t->ift_packet)
93*9022Ssam 			bcopy(p, t->ift_packet, len);
94*9022Ssam 		else
95*9022Ssam 			len = 0;
96*9022Ssam 	}
97*9022Ssam 	t->ift_size = len;
98*9022Ssam 	t->ift_metric = m;
99*9022Ssam }
100*9022Ssam 
101*9022Ssam traceaction(fd, action, rt)
102*9022Ssam 	FILE *fd;
103*9022Ssam 	char *action;
104*9022Ssam 	struct rt_entry *rt;
105*9022Ssam {
106*9022Ssam 	struct sockaddr_in *dst, *gate;
107*9022Ssam 	static struct bits {
108*9022Ssam 		int	t_bits;
109*9022Ssam 		char	*t_name;
110*9022Ssam 	} flagbits[] = {
111*9022Ssam 		{ RTF_UP,	"UP" },
112*9022Ssam 		{ RTF_GATEWAY,	"GATEWAY" },
113*9022Ssam 		{ RTF_HOST,	"HOST" },
114*9022Ssam 		{ 0 }
115*9022Ssam 	}, statebits[] = {
116*9022Ssam 		{ RTS_PASSIVE,	"PASSIVE" },
117*9022Ssam 		{ RTS_REMOTE,	"REMOTE" },
118*9022Ssam 		{ RTS_INTERFACE,"INTERFACE" },
119*9022Ssam 		{ RTS_CHANGED,	"CHANGED" },
120*9022Ssam 		{ 0 }
121*9022Ssam 	};
122*9022Ssam 	register struct bits *p;
123*9022Ssam 	register int first;
124*9022Ssam 	char *cp;
125*9022Ssam 	struct interface *ifp;
126*9022Ssam 
127*9022Ssam 	if (fd == NULL)
128*9022Ssam 		return;
129*9022Ssam 	fprintf(fd, "%s ", action);
130*9022Ssam 	dst = (struct sockaddr_in *)&rt->rt_dst;
131*9022Ssam 	gate = (struct sockaddr_in *)&rt->rt_router;
132*9022Ssam 	fprintf(fd, "dst %x, router %x, metric %d, flags", dst->sin_addr,
133*9022Ssam 		gate->sin_addr, rt->rt_metric);
134*9022Ssam 	cp = " %s";
135*9022Ssam 	for (first = 1, p = flagbits; p->t_bits > 0; p++) {
136*9022Ssam 		if ((rt->rt_flags & p->t_bits) == 0)
137*9022Ssam 			continue;
138*9022Ssam 		fprintf(fd, cp, p->t_name);
139*9022Ssam 		if (first) {
140*9022Ssam 			cp = "|%s";
141*9022Ssam 			first = 0;
142*9022Ssam 		}
143*9022Ssam 	}
144*9022Ssam 	fprintf(fd, " state");
145*9022Ssam 	cp = " %s";
146*9022Ssam 	for (first = 1, p = statebits; p->t_bits > 0; p++) {
147*9022Ssam 		if ((rt->rt_state & p->t_bits) == 0)
148*9022Ssam 			continue;
149*9022Ssam 		fprintf(fd, cp, p->t_name);
150*9022Ssam 		if (first) {
151*9022Ssam 			cp = "|%s";
152*9022Ssam 			first = 0;
153*9022Ssam 		}
154*9022Ssam 	}
155*9022Ssam 	putc('\n', fd);
156*9022Ssam 	if ((rt->rt_state & RTS_PASSIVE) == 0 && rt->rt_ifp)
157*9022Ssam 		dumpif(fd, rt->rt_ifp);
158*9022Ssam 	fflush(fd);
159*9022Ssam }
160*9022Ssam 
161*9022Ssam dumpif(fd, ifp)
162*9022Ssam 	register struct interface *ifp;
163*9022Ssam {
164*9022Ssam 	register struct ifdebug *ifd;
165*9022Ssam 
166*9022Ssam 	fprintf(fd, "*** Packet history for interface %s ***\n",
167*9022Ssam 		ifp->int_name);
168*9022Ssam 	dumptrace(fd, "to", &ifp->int_output);
169*9022Ssam 	dumptrace(fd, "from", &ifp->int_output);
170*9022Ssam 	fprintf(fd, "*** end packet history ***\n");
171*9022Ssam }
172*9022Ssam 
173*9022Ssam dumptrace(fd, dir, ifd)
174*9022Ssam 	FILE *fd;
175*9022Ssam 	char *dir;
176*9022Ssam 	register struct ifdebug *ifd;
177*9022Ssam {
178*9022Ssam 	register struct iftrace *t;
179*9022Ssam 	char *cp = !strcmp(dir, "to") ? "Output" : "Input";
180*9022Ssam 
181*9022Ssam 	if (ifd->ifd_front == ifd->ifd_records &&
182*9022Ssam 	    ifd->ifd_front->ift_size == 0) {
183*9022Ssam 		fprintf(fd, "%s: no packets.\n", cp);
184*9022Ssam 		return;
185*9022Ssam 	}
186*9022Ssam 	fprintf(fd, "%s trace:\n", cp);
187*9022Ssam 	for (t = ifd->ifd_front; t <= ifd->ifd_records + NRECORDS; t++) {
188*9022Ssam 		if (t->ift_size == 0)
189*9022Ssam 			continue;
190*9022Ssam 		fprintf(fd, "%.24s: metric=%d\n", ctime(&t->ift_stamp),
191*9022Ssam 			t->ift_metric);
192*9022Ssam 		dumppacket(fd, dir, &t->ift_who, t->ift_packet, t->ift_size);
193*9022Ssam 	}
194*9022Ssam 	for (t = ifd->ifd_records; t < ifd->ifd_front; t++) {
195*9022Ssam 		if (t->ift_size == 0)
196*9022Ssam 			continue;
197*9022Ssam 		fprintf(fd, "%.24s: metric=%d\n", ctime(&t->ift_stamp),
198*9022Ssam 			t->ift_metric);
199*9022Ssam 		dumppacket(fd, dir, &t->ift_who, t->ift_packet, t->ift_size);
200*9022Ssam 	}
201*9022Ssam }
202*9022Ssam 
203*9022Ssam dumppacket(fd, dir, who, cp, size)
204*9022Ssam 	FILE *fd;
205*9022Ssam 	struct sockaddr_in *who;		/* should be sockaddr */
206*9022Ssam 	char *dir, *cp;
207*9022Ssam 	register int size;
208*9022Ssam {
209*9022Ssam 	register struct rip *msg = (struct rip *)cp;
210*9022Ssam 	register struct netinfo *n;
211*9022Ssam 
212*9022Ssam 	if (msg->rip_cmd && msg->rip_cmd < RIPCMD_MAX)
213*9022Ssam 		fprintf(fd, "%s %s %x.%d", ripcmds[msg->rip_cmd],
214*9022Ssam 			dir, who->sin_addr, ntohs(who->sin_port));
215*9022Ssam 	else {
216*9022Ssam 		fprintf(fd, "Bad cmd 0x%x %s %x.%d\n", msg->rip_cmd,
217*9022Ssam 			dir, who->sin_addr, ntohs(who->sin_port));
218*9022Ssam 		fprintf(fd, "size=%d cp=%x packet=%x\n", size, cp, packet);
219*9022Ssam 		return;
220*9022Ssam 	}
221*9022Ssam 	switch (msg->rip_cmd) {
222*9022Ssam 
223*9022Ssam 	case RIPCMD_REQUEST:
224*9022Ssam 	case RIPCMD_RESPONSE:
225*9022Ssam 		fprintf(fd, ":\n");
226*9022Ssam 		size -= 4 * sizeof (char);
227*9022Ssam 		n = msg->rip_nets;
228*9022Ssam 		for (; size > 0; n++, size -= sizeof (struct netinfo)) {
229*9022Ssam 			if (size < sizeof (struct netinfo))
230*9022Ssam 				break;
231*9022Ssam 			fprintf(fd, "\tdst %x metric %d\n",
232*9022Ssam 				((struct sockaddr_in *)&n->rip_dst)->sin_addr,
233*9022Ssam 				n->rip_metric);
234*9022Ssam 		}
235*9022Ssam 		break;
236*9022Ssam 
237*9022Ssam 	case RIPCMD_TRACEON:
238*9022Ssam 		fprintf(fd, ", file=%*s\n", size, msg->rip_tracefile);
239*9022Ssam 		break;
240*9022Ssam 
241*9022Ssam 	case RIPCMD_TRACEOFF:
242*9022Ssam 		fprintf(fd, "\n");
243*9022Ssam 		break;
244*9022Ssam 	}
245*9022Ssam }
246