|
|
1.1 root 1: /*
2: * Copyright (c) 1985 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: *
6: * Includes material written at Cornell University by Bill Nesheim,
7: * by permission of the author.
8: */
9:
10:
11: #ifndef lint
12: static char sccsid[] = "@(#)trace.c 5.7 (Berkeley) 10/22/87";
13: #endif not lint
14:
15: /*
16: * Routing Table Management Daemon
17: */
18: #define RIPCMDS
19: #include "defs.h"
20:
21: #define NRECORDS 50 /* size of circular trace buffer */
22: #ifdef DEBUG
23: FILE *ftrace = stdout;
24: int tracing = 1;
25: #else DEBUG
26: FILE *ftrace = NULL;
27: int tracing = 0;
28: #endif
29:
30: char *xns_ntoa();
31:
32: traceinit(ifp)
33: register struct interface *ifp;
34: {
35:
36: if (iftraceinit(ifp, &ifp->int_input) &&
37: iftraceinit(ifp, &ifp->int_output))
38: return;
39: tracing = 0;
40: syslog(LOG_ERR, "traceinit: can't init %s\n", ifp->int_name);
41: }
42:
43: static
44: iftraceinit(ifp, ifd)
45: struct interface *ifp;
46: register struct ifdebug *ifd;
47: {
48: register struct iftrace *t;
49:
50: ifd->ifd_records =
51: (struct iftrace *)malloc(NRECORDS * sizeof (struct iftrace));
52: if (ifd->ifd_records == 0)
53: return (0);
54: ifd->ifd_front = ifd->ifd_records;
55: ifd->ifd_count = 0;
56: for (t = ifd->ifd_records; t < ifd->ifd_records + NRECORDS; t++) {
57: t->ift_size = 0;
58: t->ift_packet = 0;
59: }
60: ifd->ifd_if = ifp;
61: return (1);
62: }
63:
64: traceon(file)
65: char *file;
66: {
67:
68: if (ftrace != NULL)
69: return;
70: ftrace = fopen(file, "a");
71: if (ftrace == NULL)
72: return;
73: dup2(fileno(ftrace), 1);
74: dup2(fileno(ftrace), 2);
75: tracing = 1;
76: }
77:
78: traceoff()
79: {
80: if (!tracing)
81: return;
82: if (ftrace != NULL)
83: fclose(ftrace);
84: ftrace = NULL;
85: tracing = 0;
86: }
87:
88: trace(ifd, who, p, len, m)
89: register struct ifdebug *ifd;
90: struct sockaddr *who;
91: char *p;
92: int len, m;
93: {
94: register struct iftrace *t;
95:
96: if (ifd->ifd_records == 0)
97: return;
98: t = ifd->ifd_front++;
99: if (ifd->ifd_front >= ifd->ifd_records + NRECORDS)
100: ifd->ifd_front = ifd->ifd_records;
101: if (ifd->ifd_count < NRECORDS)
102: ifd->ifd_count++;
103: if (t->ift_size > 0 && t->ift_packet)
104: free(t->ift_packet);
105: t->ift_packet = 0;
106: t->ift_stamp = time(0);
107: t->ift_who = *who;
108: if (len > 0) {
109: t->ift_packet = malloc(len);
110: if (t->ift_packet)
111: bcopy(p, t->ift_packet, len);
112: else
113: len = 0;
114: }
115: t->ift_size = len;
116: t->ift_metric = m;
117: }
118:
119: traceaction(fd, action, rt)
120: FILE *fd;
121: char *action;
122: struct rt_entry *rt;
123: {
124: struct sockaddr_ns *dst, *gate;
125: static struct bits {
126: int t_bits;
127: char *t_name;
128: } flagbits[] = {
129: { RTF_UP, "UP" },
130: { RTF_GATEWAY, "GATEWAY" },
131: { RTF_HOST, "HOST" },
132: { 0 }
133: }, statebits[] = {
134: { RTS_PASSIVE, "PASSIVE" },
135: { RTS_REMOTE, "REMOTE" },
136: { RTS_INTERFACE,"INTERFACE" },
137: { RTS_CHANGED, "CHANGED" },
138: { 0 }
139: };
140: register struct bits *p;
141: register int first;
142: char *cp;
143: struct interface *ifp;
144:
145: if (fd == NULL)
146: return;
147: fprintf(fd, "%s ", action);
148: dst = (struct sockaddr_ns *)&rt->rt_dst;
149: gate = (struct sockaddr_ns *)&rt->rt_router;
150: fprintf(fd, "dst %s, ", xns_ntoa(&dst->sns_addr));
151: fprintf(fd, "router %s, metric %d, flags",
152: xns_ntoa(&gate->sns_addr), rt->rt_metric);
153: cp = " %s";
154: for (first = 1, p = flagbits; p->t_bits > 0; p++) {
155: if ((rt->rt_flags & p->t_bits) == 0)
156: continue;
157: fprintf(fd, cp, p->t_name);
158: if (first) {
159: cp = "|%s";
160: first = 0;
161: }
162: }
163: fprintf(fd, " state");
164: cp = " %s";
165: for (first = 1, p = statebits; p->t_bits > 0; p++) {
166: if ((rt->rt_state & p->t_bits) == 0)
167: continue;
168: fprintf(fd, cp, p->t_name);
169: if (first) {
170: cp = "|%s";
171: first = 0;
172: }
173: }
174: putc('\n', fd);
175: if (!tracepackets && (rt->rt_state & RTS_PASSIVE) == 0 && rt->rt_ifp)
176: dumpif(fd, rt->rt_ifp);
177: fflush(fd);
178: }
179:
180: dumpif(fd, ifp)
181: register struct interface *ifp;
182: FILE *fd;
183: {
184: if (ifp->int_input.ifd_count || ifp->int_output.ifd_count) {
185: fprintf(fd, "*** Packet history for interface %s ***\n",
186: ifp->int_name);
187: dumptrace(fd, "to", &ifp->int_output);
188: dumptrace(fd, "from", &ifp->int_input);
189: fprintf(fd, "*** end packet history ***\n");
190: }
191: }
192:
193: dumptrace(fd, dir, ifd)
194: FILE *fd;
195: char *dir;
196: register struct ifdebug *ifd;
197: {
198: register struct iftrace *t;
199: char *cp = !strcmp(dir, "to") ? "Output" : "Input";
200:
201: if (ifd->ifd_front == ifd->ifd_records &&
202: ifd->ifd_front->ift_size == 0) {
203: fprintf(fd, "%s: no packets.\n", cp);
204: return;
205: }
206: fprintf(fd, "%s trace:\n", cp);
207: t = ifd->ifd_front - ifd->ifd_count;
208: if (t < ifd->ifd_records)
209: t += NRECORDS;
210: for ( ; ifd->ifd_count; ifd->ifd_count--, t++) {
211: if (t >= ifd->ifd_records + NRECORDS)
212: t = ifd->ifd_records;
213: if (t->ift_size == 0)
214: continue;
215: fprintf(fd, "%.24s: metric=%d\n", ctime(&t->ift_stamp),
216: t->ift_metric);
217: dumppacket(fd, dir, &t->ift_who, t->ift_packet, t->ift_size);
218: }
219: }
220:
221: dumppacket(fd, dir, who, cp, size)
222: FILE *fd;
223: struct sockaddr_ns *who; /* should be sockaddr */
224: char *dir, *cp;
225: register int size;
226: {
227: register struct rip *msg = (struct rip *)cp;
228: register struct netinfo *n;
229: char *xns_nettoa();
230:
231: if (msg->rip_cmd && ntohs(msg->rip_cmd) < RIPCMD_MAX)
232: fprintf(fd, "%s %s %s#%x", ripcmds[ntohs(msg->rip_cmd)],
233: dir, xns_ntoa(&who->sns_addr), ntohs(who->sns_addr.x_port));
234: else {
235: fprintf(fd, "Bad cmd 0x%x %s %s#%x\n", ntohs(msg->rip_cmd),
236: dir, xns_ntoa(&who->sns_addr), ntohs(who->sns_addr.x_port));
237: fprintf(fd, "size=%d cp=%x packet=%x\n", size, cp, packet);
238: return;
239: }
240: switch (ntohs(msg->rip_cmd)) {
241:
242: case RIPCMD_REQUEST:
243: case RIPCMD_RESPONSE:
244: fprintf(fd, ":\n");
245: size -= sizeof (u_short);
246: n = msg->rip_nets;
247: for (; size > 0; n++, size -= sizeof (struct netinfo)) {
248: if (size < sizeof (struct netinfo))
249: break;
250: fprintf(fd, "\tnet %s metric %d\n",
251: xns_nettoa(n->rip_dst),
252: ntohs(n->rip_metric));
253: }
254: break;
255:
256: }
257: }
258:
259: union ns_net_u net;
260:
261: char *
262: xns_nettoa(val)
263: union ns_net val;
264: {
265: static char buf[100];
266: net.net_e = val;
267: (void)sprintf(buf, "%lx", ntohl(net.long_e));
268: return (buf);
269: }
270:
271:
272: char *
273: xns_ntoa(addr)
274: struct ns_addr *addr;
275: {
276: static char buf[100];
277:
278: (void)sprintf(buf, "%s#%x:%x:%x:%x:%x:%x",
279: xns_nettoa(addr->x_net),
280: addr->x_host.c_host[0], addr->x_host.c_host[1],
281: addr->x_host.c_host[2], addr->x_host.c_host[3],
282: addr->x_host.c_host[4], addr->x_host.c_host[5]);
283:
284: return(buf);
285: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.