add optional nbpi to specify "number of bytes per inode"
[unix-history] / usr / src / sbin / routed / trace.c
CommitLineData
f036a54d 1#ifndef lint
7fe7fe74 2static char sccsid[] = "@(#)trace.c 4.2 %G%";
f036a54d
SL
3#endif
4
5/*
6 * Routing Table Management Daemon
7 */
8#define RIPCMDS
7fe7fe74 9#include "defs.h"
f036a54d
SL
10
11#define NRECORDS 50 /* size of circular trace buffer */
12#ifdef DEBUG
13FILE *ftrace = stdout;
14int tracing = 1;
15#endif
16
17traceinit(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
28static
29iftraceinit(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
48traceon(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
62traceoff()
63{
64 if (!tracing)
65 return;
66 if (ftrace != NULL)
67 fclose(ftrace);
68 ftrace = NULL;
69 tracing = 0;
70}
71
72trace(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
101traceaction(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 %x, router %x, metric %d, flags", dst->sin_addr,
133 gate->sin_addr, rt->rt_metric);
134 cp = " %s";
135 for (first = 1, p = flagbits; p->t_bits > 0; p++) {
136 if ((rt->rt_flags & p->t_bits) == 0)
137 continue;
138 fprintf(fd, cp, p->t_name);
139 if (first) {
140 cp = "|%s";
141 first = 0;
142 }
143 }
144 fprintf(fd, " state");
145 cp = " %s";
146 for (first = 1, p = statebits; p->t_bits > 0; p++) {
147 if ((rt->rt_state & p->t_bits) == 0)
148 continue;
149 fprintf(fd, cp, p->t_name);
150 if (first) {
151 cp = "|%s";
152 first = 0;
153 }
154 }
155 putc('\n', fd);
156 if ((rt->rt_state & RTS_PASSIVE) == 0 && rt->rt_ifp)
157 dumpif(fd, rt->rt_ifp);
158 fflush(fd);
159}
160
161dumpif(fd, ifp)
162 register struct interface *ifp;
163{
164 register struct ifdebug *ifd;
165
166 fprintf(fd, "*** Packet history for interface %s ***\n",
167 ifp->int_name);
168 dumptrace(fd, "to", &ifp->int_output);
169 dumptrace(fd, "from", &ifp->int_output);
170 fprintf(fd, "*** end packet history ***\n");
171}
172
173dumptrace(fd, dir, ifd)
174 FILE *fd;
175 char *dir;
176 register struct ifdebug *ifd;
177{
178 register struct iftrace *t;
179 char *cp = !strcmp(dir, "to") ? "Output" : "Input";
180
181 if (ifd->ifd_front == ifd->ifd_records &&
182 ifd->ifd_front->ift_size == 0) {
183 fprintf(fd, "%s: no packets.\n", cp);
184 return;
185 }
186 fprintf(fd, "%s trace:\n", cp);
187 for (t = ifd->ifd_front; t <= ifd->ifd_records + NRECORDS; t++) {
188 if (t->ift_size == 0)
189 continue;
190 fprintf(fd, "%.24s: metric=%d\n", ctime(&t->ift_stamp),
191 t->ift_metric);
192 dumppacket(fd, dir, &t->ift_who, t->ift_packet, t->ift_size);
193 }
194 for (t = ifd->ifd_records; t < ifd->ifd_front; t++) {
195 if (t->ift_size == 0)
196 continue;
197 fprintf(fd, "%.24s: metric=%d\n", ctime(&t->ift_stamp),
198 t->ift_metric);
199 dumppacket(fd, dir, &t->ift_who, t->ift_packet, t->ift_size);
200 }
201}
202
203dumppacket(fd, dir, who, cp, size)
204 FILE *fd;
205 struct sockaddr_in *who; /* should be sockaddr */
206 char *dir, *cp;
207 register int size;
208{
209 register struct rip *msg = (struct rip *)cp;
210 register struct netinfo *n;
211
212 if (msg->rip_cmd && msg->rip_cmd < RIPCMD_MAX)
213 fprintf(fd, "%s %s %x.%d", ripcmds[msg->rip_cmd],
214 dir, who->sin_addr, ntohs(who->sin_port));
215 else {
216 fprintf(fd, "Bad cmd 0x%x %s %x.%d\n", msg->rip_cmd,
217 dir, who->sin_addr, ntohs(who->sin_port));
218 fprintf(fd, "size=%d cp=%x packet=%x\n", size, cp, packet);
219 return;
220 }
221 switch (msg->rip_cmd) {
222
223 case RIPCMD_REQUEST:
224 case RIPCMD_RESPONSE:
225 fprintf(fd, ":\n");
226 size -= 4 * sizeof (char);
227 n = msg->rip_nets;
228 for (; size > 0; n++, size -= sizeof (struct netinfo)) {
229 if (size < sizeof (struct netinfo))
230 break;
231 fprintf(fd, "\tdst %x metric %d\n",
232 ((struct sockaddr_in *)&n->rip_dst)->sin_addr,
233 n->rip_metric);
234 }
235 break;
236
237 case RIPCMD_TRACEON:
238 fprintf(fd, ", file=%*s\n", size, msg->rip_tracefile);
239 break;
240
241 case RIPCMD_TRACEOFF:
242 fprintf(fd, "\n");
243 break;
244 }
245}