|
|
1.1 root 1: /*
2: * Copyright (c) 1983, 1988 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted
6: * provided that the above copyright notice and this paragraph are
7: * duplicated in all such forms and that any documentation,
8: * advertising materials, and other materials related to such
9: * distribution and use acknowledge that the software was developed
10: * by the University of California, Berkeley. The name of the
11: * University may not be used to endorse or promote products derived
12: * from this software without specific prior written permission.
13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16: */
17:
18: #ifndef lint
19: static char sccsid[] = "@(#)trace.c 5.7 (Berkeley) 6/18/88";
20: #endif /* not lint */
21:
22: /*
23: * Routing Table Management Daemon
24: */
25: #define RIPCMDS
26: #include "defs.h"
27: #include <sys/file.h>
28: #include <sys/stat.h>
29: #include <sys/signal.h>
30:
31: #define NRECORDS 50 /* size of circular trace buffer */
32: #ifdef DEBUG
33: FILE *ftrace = stdout;
34: int traceactions = 1;
35: #endif
36:
37: traceinit(ifp)
38: register struct interface *ifp;
39: {
40:
41: if (iftraceinit(ifp, &ifp->int_input) &&
42: iftraceinit(ifp, &ifp->int_output))
43: return;
44: tracehistory = 0;
45: fprintf(stderr, "traceinit: can't init %s\n", ifp->int_name);
46: }
47:
48: static
49: iftraceinit(ifp, ifd)
50: struct interface *ifp;
51: register struct ifdebug *ifd;
52: {
53: register struct iftrace *t;
54:
55: ifd->ifd_records =
56: (struct iftrace *)malloc(NRECORDS * sizeof (struct iftrace));
57: if (ifd->ifd_records == 0)
58: return (0);
59: ifd->ifd_front = ifd->ifd_records;
60: ifd->ifd_count = 0;
61: for (t = ifd->ifd_records; t < ifd->ifd_records + NRECORDS; t++) {
62: t->ift_size = 0;
63: t->ift_packet = 0;
64: }
65: ifd->ifd_if = ifp;
66: return (1);
67: }
68:
69: traceon(file)
70: char *file;
71: {
72: struct stat stbuf;
73:
74: if (ftrace != NULL)
75: return;
76: if (stat(file, &stbuf) >= 0 && (stbuf.st_mode & S_IFMT) != S_IFREG)
77: return;
78: ftrace = fopen(file, "a");
79: if (ftrace == NULL)
80: return;
81: dup2(fileno(ftrace), 1);
82: dup2(fileno(ftrace), 2);
83: traceactions = 1;
84: }
85:
86: traceoff()
87: {
88: if (!traceactions)
89: return;
90: if (ftrace != NULL) {
91: int fd = open("/dev/null", O_RDWR);
92:
93: fprintf(ftrace, "Tracing disabled\n");
94: (void) dup2(fd, 1);
95: (void) dup2(fd, 2);
96: (void) close(fd);
97: fclose(ftrace);
98: ftrace = NULL;
99: }
100: traceactions = 0;
101: tracehistory = 0;
102: }
103:
104: sigtrace(s)
105: int s;
106: {
107: if (s == SIGUSR2) {
108: traceoff();
109: tracepackets = 0;
110: } else if (traceactions == 0)
111: traceactions++;
112: else if (tracehistory == 0)
113: tracehistory++;
114: else {
115: tracepackets++;
116: tracehistory = 0;
117: }
118: }
119:
120: trace(ifd, who, p, len, m)
121: register struct ifdebug *ifd;
122: struct sockaddr *who;
123: char *p;
124: int len, m;
125: {
126: register struct iftrace *t;
127:
128: if (ifd->ifd_records == 0)
129: return;
130: t = ifd->ifd_front++;
131: if (ifd->ifd_front >= ifd->ifd_records + NRECORDS)
132: ifd->ifd_front = ifd->ifd_records;
133: if (ifd->ifd_count < NRECORDS)
134: ifd->ifd_count++;
135: if (t->ift_size > 0 && t->ift_size < len && t->ift_packet) {
136: free(t->ift_packet);
137: t->ift_packet = 0;
138: }
139: t->ift_stamp = time(0);
140: t->ift_who = *who;
141: if (len > 0 && t->ift_packet == 0) {
142: t->ift_packet = malloc(len);
143: if (t->ift_packet == 0)
144: len = 0;
145: }
146: if (len > 0)
147: bcopy(p, t->ift_packet, len);
148: t->ift_size = len;
149: t->ift_metric = m;
150: }
151:
152: traceaction(fd, action, rt)
153: FILE *fd;
154: char *action;
155: struct rt_entry *rt;
156: {
157: struct sockaddr_in *dst, *gate;
158: static struct bits {
159: int t_bits;
160: char *t_name;
161: } flagbits[] = {
162: { RTF_UP, "UP" },
163: { RTF_GATEWAY, "GATEWAY" },
164: { RTF_HOST, "HOST" },
165: { 0 }
166: }, statebits[] = {
167: { RTS_PASSIVE, "PASSIVE" },
168: { RTS_REMOTE, "REMOTE" },
169: { RTS_INTERFACE,"INTERFACE" },
170: { RTS_CHANGED, "CHANGED" },
171: { RTS_INTERNAL, "INTERNAL" },
172: { RTS_EXTERNAL, "EXTERNAL" },
173: { RTS_SUBNET, "SUBNET" },
174: { 0 }
175: };
176: register struct bits *p;
177: register int first;
178: char *cp;
179: struct interface *ifp;
180:
181: if (fd == NULL)
182: return;
183: if (curtime) {
184: fprintf(fd, "\n%s", curtime);
185: curtime = NULL;
186: }
187: fprintf(fd, "%s ", action);
188: dst = (struct sockaddr_in *)&rt->rt_dst;
189: gate = (struct sockaddr_in *)&rt->rt_router;
190: fprintf(fd, "dst %s, ", inet_ntoa(dst->sin_addr));
191: fprintf(fd, "router %s, metric %d, flags",
192: inet_ntoa(gate->sin_addr), rt->rt_metric);
193: cp = " %s";
194: for (first = 1, p = flagbits; p->t_bits > 0; p++) {
195: if ((rt->rt_flags & p->t_bits) == 0)
196: continue;
197: fprintf(fd, cp, p->t_name);
198: if (first) {
199: cp = "|%s";
200: first = 0;
201: }
202: }
203: fprintf(fd, " state");
204: cp = " %s";
205: for (first = 1, p = statebits; p->t_bits > 0; p++) {
206: if ((rt->rt_state & p->t_bits) == 0)
207: continue;
208: fprintf(fd, cp, p->t_name);
209: if (first) {
210: cp = "|%s";
211: first = 0;
212: }
213: }
214: fprintf(fd, " timer %d\n", rt->rt_timer);
215: if (!tracepackets && (rt->rt_state & RTS_PASSIVE) == 0 && rt->rt_ifp)
216: dumpif(fd, rt->rt_ifp);
217: fflush(fd);
218: }
219:
220: tracenewmetric(fd, rt, newmetric)
221: FILE *fd;
222: struct rt_entry *rt;
223: int newmetric;
224: {
225: struct sockaddr_in *dst, *gate;
226:
227: if (fd == NULL)
228: return;
229: dst = (struct sockaddr_in *)&rt->rt_dst;
230: gate = (struct sockaddr_in *)&rt->rt_router;
231: fprintf(fd, "CHANGE metric dst %s, ", inet_ntoa(dst->sin_addr));
232: fprintf(fd, "router %s, from %d to %d\n",
233: inet_ntoa(gate->sin_addr), rt->rt_metric, newmetric);
234: fflush(fd);
235: }
236:
237: dumpif(fd, ifp)
238: register struct interface *ifp;
239: {
240: if (ifp->int_input.ifd_count || ifp->int_output.ifd_count) {
241: fprintf(fd, "*** Packet history for interface %s ***\n",
242: ifp->int_name);
243: #ifdef notneeded
244: dumptrace(fd, "to", &ifp->int_output);
245: #endif
246: dumptrace(fd, "from", &ifp->int_input);
247: fprintf(fd, "*** end packet history ***\n");
248: }
249: fflush(fd);
250: }
251:
252: dumptrace(fd, dir, ifd)
253: FILE *fd;
254: char *dir;
255: register struct ifdebug *ifd;
256: {
257: register struct iftrace *t;
258: char *cp = !strcmp(dir, "to") ? "Output" : "Input";
259:
260: if (ifd->ifd_front == ifd->ifd_records &&
261: ifd->ifd_front->ift_size == 0) {
262: fprintf(fd, "%s: no packets.\n", cp);
263: fflush(fd);
264: return;
265: }
266: fprintf(fd, "%s trace:\n", cp);
267: t = ifd->ifd_front - ifd->ifd_count;
268: if (t < ifd->ifd_records)
269: t += NRECORDS;
270: for ( ; ifd->ifd_count; ifd->ifd_count--, t++) {
271: if (t >= ifd->ifd_records + NRECORDS)
272: t = ifd->ifd_records;
273: if (t->ift_size == 0)
274: continue;
275: dumppacket(fd, dir, &t->ift_who, t->ift_packet, t->ift_size,
276: &t->ift_stamp);
277: }
278: }
279:
280: dumppacket(fd, dir, who, cp, size, tstamp)
281: FILE *fd;
282: struct sockaddr_in *who; /* should be sockaddr */
283: char *dir, *cp;
284: register int size;
285: time_t *tstamp;
286: {
287: register struct rip *msg = (struct rip *)cp;
288: register struct netinfo *n;
289:
290: if (msg->rip_cmd && msg->rip_cmd < RIPCMD_MAX)
291: fprintf(fd, "%s %s %s.%d", ripcmds[msg->rip_cmd],
292: dir, inet_ntoa(who->sin_addr), ntohs(who->sin_port));
293: else {
294: fprintf(fd, "Bad cmd 0x%x %s %x.%d %.24s\n", msg->rip_cmd,
295: dir, inet_ntoa(who->sin_addr), ntohs(who->sin_port),
296: ctime(tstamp));
297: fprintf(fd, "size=%d cp=%x packet=%x\n", size, cp, packet);
298: fflush(fd);
299: return;
300: }
301: fprintf(fd, " %.24s:\n", ctime(tstamp));
302: switch (msg->rip_cmd) {
303:
304: case RIPCMD_REQUEST:
305: case RIPCMD_RESPONSE:
306: size -= 4 * sizeof (char);
307: n = msg->rip_nets;
308: for (; size > 0; n++, size -= sizeof (struct netinfo)) {
309: if (size < sizeof (struct netinfo))
310: break;
311: fprintf(fd, "\tdst %s metric %d\n",
312: #define satosin(sa) ((struct sockaddr_in *)&sa)
313: inet_ntoa(satosin(n->rip_dst)->sin_addr),
314: ntohl(n->rip_metric));
315: }
316: break;
317:
318: case RIPCMD_TRACEON:
319: fprintf(fd, "\tfile=%*s\n", size, msg->rip_tracefile);
320: break;
321:
322: case RIPCMD_TRACEOFF:
323: break;
324: }
325: fflush(fd);
326: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.