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