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