|
|
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.