|
|
1.1 root 1: /*
2: * Copyright (c) 1983 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:
7: #ifndef lint
8: static char sccsid[] = "@(#)trace.c 5.3 (Berkeley) 5/30/86";
9: #endif not lint
10:
11: /*
12: * Routing Table Management Daemon
13: */
14: #define RIPCMDS
15: #include "defs.h"
16: #include <sys/stat.h>
17:
18: #define NRECORDS 50 /* size of circular trace buffer */
19: #ifdef DEBUG
20: FILE *ftrace = stdout;
21: int tracing = 1;
22: #endif
23:
24: traceinit(ifp)
25: register struct interface *ifp;
26: {
27:
28: if (iftraceinit(ifp, &ifp->int_input) &&
29: iftraceinit(ifp, &ifp->int_output))
30: return;
31: tracing = 0;
32: fprintf(stderr, "traceinit: can't init %s\n", ifp->int_name);
33: }
34:
35: static
36: iftraceinit(ifp, ifd)
37: struct interface *ifp;
38: register struct ifdebug *ifd;
39: {
40: register struct iftrace *t;
41:
42: ifd->ifd_records =
43: (struct iftrace *)malloc(NRECORDS * sizeof (struct iftrace));
44: if (ifd->ifd_records == 0)
45: return (0);
46: ifd->ifd_front = ifd->ifd_records;
47: ifd->ifd_count = 0;
48: for (t = ifd->ifd_records; t < ifd->ifd_records + NRECORDS; t++) {
49: t->ift_size = 0;
50: t->ift_packet = 0;
51: }
52: ifd->ifd_if = ifp;
53: return (1);
54: }
55:
56: traceon(file)
57: char *file;
58: {
59: struct stat stbuf;
60:
61: if (ftrace != NULL)
62: return;
63: if (stat(file, &stbuf) >= 0 && (stbuf.st_mode & S_IFMT) != S_IFREG)
64: return;
65: ftrace = fopen(file, "a");
66: if (ftrace == NULL)
67: return;
68: dup2(fileno(ftrace), 1);
69: dup2(fileno(ftrace), 2);
70: tracing = 1;
71: }
72:
73: traceoff()
74: {
75: if (!tracing)
76: return;
77: if (ftrace != NULL)
78: fclose(ftrace);
79: ftrace = NULL;
80: tracing = 0;
81: }
82:
83: trace(ifd, who, p, len, m)
84: register struct ifdebug *ifd;
85: struct sockaddr *who;
86: char *p;
87: int len, m;
88: {
89: register struct iftrace *t;
90:
91: if (ifd->ifd_records == 0)
92: return;
93: t = ifd->ifd_front++;
94: if (ifd->ifd_front >= ifd->ifd_records + NRECORDS)
95: ifd->ifd_front = ifd->ifd_records;
96: if (ifd->ifd_count < NRECORDS)
97: ifd->ifd_count++;
98: if (t->ift_size > 0 && t->ift_size < len && t->ift_packet) {
99: free(t->ift_packet);
100: t->ift_packet = 0;
101: }
102: t->ift_stamp = time(0);
103: t->ift_who = *who;
104: if (len > 0 && t->ift_packet == 0) {
105: t->ift_packet = malloc(len);
106: if (t->ift_packet == 0)
107: len = 0;
108: }
109: if (len > 0)
110: bcopy(p, t->ift_packet, len);
111: t->ift_size = len;
112: t->ift_metric = m;
113: }
114:
115: traceaction(fd, action, rt)
116: FILE *fd;
117: char *action;
118: struct rt_entry *rt;
119: {
120: struct sockaddr_in *dst, *gate;
121: static struct bits {
122: int t_bits;
123: char *t_name;
124: } flagbits[] = {
125: { RTF_UP, "UP" },
126: { RTF_GATEWAY, "GATEWAY" },
127: { RTF_HOST, "HOST" },
128: { 0 }
129: }, statebits[] = {
130: { RTS_PASSIVE, "PASSIVE" },
131: { RTS_REMOTE, "REMOTE" },
132: { RTS_INTERFACE,"INTERFACE" },
133: { RTS_CHANGED, "CHANGED" },
134: { RTS_INTERNAL, "INTERNAL" },
135: { RTS_EXTERNAL, "EXTERNAL" },
136: { RTS_SUBNET, "SUBNET" },
137: { 0 }
138: };
139: register struct bits *p;
140: register int first;
141: char *cp;
142: struct interface *ifp;
143:
144: if (fd == NULL)
145: return;
146: fprintf(fd, "%s ", action);
147: dst = (struct sockaddr_in *)&rt->rt_dst;
148: gate = (struct sockaddr_in *)&rt->rt_router;
149: fprintf(fd, "dst %s, ", inet_ntoa(dst->sin_addr));
150: fprintf(fd, "router %s, metric %d, flags",
151: inet_ntoa(gate->sin_addr), rt->rt_metric);
152: cp = " %s";
153: for (first = 1, p = flagbits; p->t_bits > 0; p++) {
154: if ((rt->rt_flags & p->t_bits) == 0)
155: continue;
156: fprintf(fd, cp, p->t_name);
157: if (first) {
158: cp = "|%s";
159: first = 0;
160: }
161: }
162: fprintf(fd, " state");
163: cp = " %s";
164: for (first = 1, p = statebits; p->t_bits > 0; p++) {
165: if ((rt->rt_state & p->t_bits) == 0)
166: continue;
167: fprintf(fd, cp, p->t_name);
168: if (first) {
169: cp = "|%s";
170: first = 0;
171: }
172: }
173: putc('\n', fd);
174: if (!tracepackets && (rt->rt_state & RTS_PASSIVE) == 0 && rt->rt_ifp)
175: dumpif(fd, rt->rt_ifp);
176: fflush(fd);
177: }
178:
179: dumpif(fd, ifp)
180: register struct interface *ifp;
181: {
182: if (ifp->int_input.ifd_count || ifp->int_output.ifd_count) {
183: fprintf(fd, "*** Packet history for interface %s ***\n",
184: ifp->int_name);
185: dumptrace(fd, "to", &ifp->int_output);
186: dumptrace(fd, "from", &ifp->int_input);
187: fprintf(fd, "*** end packet history ***\n");
188: }
189: fflush(fd);
190: }
191:
192: dumptrace(fd, dir, ifd)
193: FILE *fd;
194: char *dir;
195: register struct ifdebug *ifd;
196: {
197: register struct iftrace *t;
198: char *cp = !strcmp(dir, "to") ? "Output" : "Input";
199:
200: if (ifd->ifd_front == ifd->ifd_records &&
201: ifd->ifd_front->ift_size == 0) {
202: fprintf(fd, "%s: no packets.\n", cp);
203: fflush(fd);
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_in *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:
230: if (msg->rip_cmd && msg->rip_cmd < RIPCMD_MAX)
231: fprintf(fd, "%s %s %s.%d", ripcmds[msg->rip_cmd],
232: dir, inet_ntoa(who->sin_addr), ntohs(who->sin_port));
233: else {
234: fprintf(fd, "Bad cmd 0x%x %s %x.%d\n", msg->rip_cmd,
235: dir, inet_ntoa(who->sin_addr), ntohs(who->sin_port));
236: fprintf(fd, "size=%d cp=%x packet=%x\n", size, cp, packet);
237: fflush(fd);
238: return;
239: }
240: switch (msg->rip_cmd) {
241:
242: case RIPCMD_REQUEST:
243: case RIPCMD_RESPONSE:
244: fprintf(fd, ":\n");
245: size -= 4 * sizeof (char);
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, "\tdst %s metric %d\n",
251: #define satosin(sa) ((struct sockaddr_in *)&sa)
252: inet_ntoa(satosin(n->rip_dst)->sin_addr),
253: ntohl(n->rip_metric));
254: }
255: break;
256:
257: case RIPCMD_TRACEON:
258: fprintf(fd, ", file=%*s\n", size, msg->rip_tracefile);
259: break;
260:
261: case RIPCMD_TRACEOFF:
262: fprintf(fd, "\n");
263: break;
264: }
265: fflush(fd);
266: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.