1 #ifndef lint 2 static char sccsid[] = "@(#)trace.c 4.1 11/02/82"; 3 #endif 4 5 /* 6 * Routing Table Management Daemon 7 */ 8 #define RIPCMDS 9 #include "router.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 %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 161 dumpif(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 173 dumptrace(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 203 dumppacket(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 } 246