|
|
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: (1) source distributions retain this entire copyright ! 7: * notice and comment, and (2) distributions including binaries display ! 8: * the following acknowledgement: ``This product includes software ! 9: * developed by the University of California, Berkeley and its contributors'' ! 10: * in the documentation or other materials provided with the distribution ! 11: * and in all advertising materials mentioning features or use of this ! 12: * software. Neither the name of the University nor the names of its ! 13: * contributors may be used to endorse or promote products derived ! 14: * from this software without specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: static char sccsid[] = "@(#)trace.c 5.10 (Berkeley) 6/1/90"; ! 22: #endif /* not lint */ ! 23: ! 24: /* ! 25: * Routing Table Management Daemon ! 26: */ ! 27: #define RIPCMDS ! 28: #include "defs.h" ! 29: #include <sys/file.h> ! 30: #include <sys/stat.h> ! 31: #include <sys/signal.h> ! 32: #include "pathnames.h" ! 33: ! 34: #define NRECORDS 50 /* size of circular trace buffer */ ! 35: #ifdef DEBUG ! 36: FILE *ftrace = stdout; ! 37: int traceactions = 0; ! 38: #endif ! 39: static struct timeval lastlog; ! 40: static char *savetracename; ! 41: ! 42: traceinit(ifp) ! 43: register struct interface *ifp; ! 44: { ! 45: ! 46: if (iftraceinit(ifp, &ifp->int_input) && ! 47: iftraceinit(ifp, &ifp->int_output)) ! 48: return; ! 49: tracehistory = 0; ! 50: fprintf(stderr, "traceinit: can't init %s\n", ifp->int_name); ! 51: } ! 52: ! 53: static ! 54: iftraceinit(ifp, ifd) ! 55: struct interface *ifp; ! 56: register struct ifdebug *ifd; ! 57: { ! 58: register struct iftrace *t; ! 59: ! 60: ifd->ifd_records = ! 61: (struct iftrace *)malloc(NRECORDS * sizeof (struct iftrace)); ! 62: if (ifd->ifd_records == 0) ! 63: return (0); ! 64: ifd->ifd_front = ifd->ifd_records; ! 65: ifd->ifd_count = 0; ! 66: for (t = ifd->ifd_records; t < ifd->ifd_records + NRECORDS; t++) { ! 67: t->ift_size = 0; ! 68: t->ift_packet = 0; ! 69: } ! 70: ifd->ifd_if = ifp; ! 71: return (1); ! 72: } ! 73: ! 74: traceon(file) ! 75: char *file; ! 76: { ! 77: struct stat stbuf; ! 78: ! 79: if (ftrace != NULL) ! 80: return; ! 81: if (stat(file, &stbuf) >= 0 && (stbuf.st_mode & S_IFMT) != S_IFREG) ! 82: return; ! 83: savetracename = file; ! 84: (void) gettimeofday(&now, (struct timezone *)NULL); ! 85: ftrace = fopen(file, "a"); ! 86: if (ftrace == NULL) ! 87: return; ! 88: dup2(fileno(ftrace), 1); ! 89: dup2(fileno(ftrace), 2); ! 90: traceactions = 1; ! 91: fprintf(ftrace, "Tracing enabled %s\n", ctime((time_t *)&now.tv_sec)); ! 92: } ! 93: ! 94: traceoff() ! 95: { ! 96: if (!traceactions) ! 97: return; ! 98: if (ftrace != NULL) { ! 99: int fd = open(_PATH_DEVNULL, O_RDWR); ! 100: ! 101: fprintf(ftrace, "Tracing disabled %s\n", ! 102: ctime((time_t *)&now.tv_sec)); ! 103: fflush(ftrace); ! 104: (void) dup2(fd, 1); ! 105: (void) dup2(fd, 2); ! 106: (void) close(fd); ! 107: fclose(ftrace); ! 108: ftrace = NULL; ! 109: } ! 110: traceactions = 0; ! 111: tracehistory = 0; ! 112: tracepackets = 0; ! 113: tracecontents = 0; ! 114: } ! 115: ! 116: sigtrace(s) ! 117: int s; ! 118: { ! 119: ! 120: if (s == SIGUSR2) ! 121: traceoff(); ! 122: else if (ftrace == NULL && savetracename) ! 123: traceon(savetracename); ! 124: else ! 125: bumploglevel(); ! 126: } ! 127: ! 128: /* ! 129: * Move to next higher level of tracing when -t option processed or ! 130: * SIGUSR1 is received. Successive levels are: ! 131: * traceactions ! 132: * traceactions + tracepackets ! 133: * traceactions + tracehistory (packets and contents after change) ! 134: * traceactions + tracepackets + tracecontents ! 135: */ ! 136: bumploglevel() ! 137: { ! 138: ! 139: (void) gettimeofday(&now, (struct timezone *)NULL); ! 140: if (traceactions == 0) { ! 141: traceactions++; ! 142: if (ftrace) ! 143: fprintf(ftrace, "Tracing actions started %s\n", ! 144: ctime((time_t *)&now.tv_sec)); ! 145: } else if (tracepackets == 0) { ! 146: tracepackets++; ! 147: tracehistory = 0; ! 148: tracecontents = 0; ! 149: if (ftrace) ! 150: fprintf(ftrace, "Tracing packets started %s\n", ! 151: ctime((time_t *)&now.tv_sec)); ! 152: } else if (tracehistory == 0) { ! 153: tracehistory++; ! 154: if (ftrace) ! 155: fprintf(ftrace, "Tracing history started %s\n", ! 156: ctime((time_t *)&now.tv_sec)); ! 157: } else { ! 158: tracepackets++; ! 159: tracecontents++; ! 160: tracehistory = 0; ! 161: if (ftrace) ! 162: fprintf(ftrace, "Tracing packet contents started %s\n", ! 163: ctime((time_t *)&now.tv_sec)); ! 164: } ! 165: if (ftrace) ! 166: fflush(ftrace); ! 167: } ! 168: ! 169: trace(ifd, who, p, len, m) ! 170: register struct ifdebug *ifd; ! 171: struct sockaddr *who; ! 172: char *p; ! 173: int len, m; ! 174: { ! 175: register struct iftrace *t; ! 176: ! 177: if (ifd->ifd_records == 0) ! 178: return; ! 179: t = ifd->ifd_front++; ! 180: if (ifd->ifd_front >= ifd->ifd_records + NRECORDS) ! 181: ifd->ifd_front = ifd->ifd_records; ! 182: if (ifd->ifd_count < NRECORDS) ! 183: ifd->ifd_count++; ! 184: if (t->ift_size > 0 && t->ift_size < len && t->ift_packet) { ! 185: free(t->ift_packet); ! 186: t->ift_packet = 0; ! 187: } ! 188: t->ift_stamp = now; ! 189: t->ift_who = *who; ! 190: if (len > 0 && t->ift_packet == 0) { ! 191: t->ift_packet = malloc(len); ! 192: if (t->ift_packet == 0) ! 193: len = 0; ! 194: } ! 195: if (len > 0) ! 196: bcopy(p, t->ift_packet, len); ! 197: t->ift_size = len; ! 198: t->ift_metric = m; ! 199: } ! 200: ! 201: traceaction(fd, action, rt) ! 202: FILE *fd; ! 203: char *action; ! 204: struct rt_entry *rt; ! 205: { ! 206: struct sockaddr_in *dst, *gate; ! 207: static struct bits { ! 208: int t_bits; ! 209: char *t_name; ! 210: } flagbits[] = { ! 211: { RTF_UP, "UP" }, ! 212: { RTF_GATEWAY, "GATEWAY" }, ! 213: { RTF_HOST, "HOST" }, ! 214: { 0 } ! 215: }, statebits[] = { ! 216: { RTS_PASSIVE, "PASSIVE" }, ! 217: { RTS_REMOTE, "REMOTE" }, ! 218: { RTS_INTERFACE,"INTERFACE" }, ! 219: { RTS_CHANGED, "CHANGED" }, ! 220: { RTS_INTERNAL, "INTERNAL" }, ! 221: { RTS_EXTERNAL, "EXTERNAL" }, ! 222: { RTS_SUBNET, "SUBNET" }, ! 223: { 0 } ! 224: }; ! 225: register struct bits *p; ! 226: register int first; ! 227: char *cp; ! 228: struct interface *ifp; ! 229: ! 230: if (fd == NULL) ! 231: return; ! 232: if (lastlog.tv_sec != now.tv_sec || lastlog.tv_usec != now.tv_usec) { ! 233: fprintf(fd, "\n%.19s:\n", ctime((time_t *)&now.tv_sec)); ! 234: lastlog = now; ! 235: } ! 236: fprintf(fd, "%s ", action); ! 237: dst = (struct sockaddr_in *)&rt->rt_dst; ! 238: gate = (struct sockaddr_in *)&rt->rt_router; ! 239: fprintf(fd, "dst %s, ", inet_ntoa(dst->sin_addr)); ! 240: fprintf(fd, "router %s, metric %d, flags", ! 241: inet_ntoa(gate->sin_addr), rt->rt_metric); ! 242: cp = " %s"; ! 243: for (first = 1, p = flagbits; p->t_bits > 0; p++) { ! 244: if ((rt->rt_flags & p->t_bits) == 0) ! 245: continue; ! 246: fprintf(fd, cp, p->t_name); ! 247: if (first) { ! 248: cp = "|%s"; ! 249: first = 0; ! 250: } ! 251: } ! 252: fprintf(fd, " state"); ! 253: cp = " %s"; ! 254: for (first = 1, p = statebits; p->t_bits > 0; p++) { ! 255: if ((rt->rt_state & p->t_bits) == 0) ! 256: continue; ! 257: fprintf(fd, cp, p->t_name); ! 258: if (first) { ! 259: cp = "|%s"; ! 260: first = 0; ! 261: } ! 262: } ! 263: fprintf(fd, " timer %d\n", rt->rt_timer); ! 264: if (tracehistory && !tracepackets && ! 265: (rt->rt_state & RTS_PASSIVE) == 0 && rt->rt_ifp) ! 266: dumpif(fd, rt->rt_ifp); ! 267: fflush(fd); ! 268: if (ferror(fd)) ! 269: traceoff(); ! 270: } ! 271: ! 272: tracenewmetric(fd, rt, newmetric) ! 273: FILE *fd; ! 274: struct rt_entry *rt; ! 275: int newmetric; ! 276: { ! 277: struct sockaddr_in *dst, *gate; ! 278: ! 279: if (fd == NULL) ! 280: return; ! 281: if (lastlog.tv_sec != now.tv_sec || lastlog.tv_usec != now.tv_usec) { ! 282: fprintf(fd, "\n%.19s:\n", ctime((time_t *)&now.tv_sec)); ! 283: lastlog = now; ! 284: } ! 285: dst = (struct sockaddr_in *)&rt->rt_dst; ! 286: gate = (struct sockaddr_in *)&rt->rt_router; ! 287: fprintf(fd, "CHANGE metric dst %s, ", inet_ntoa(dst->sin_addr)); ! 288: fprintf(fd, "router %s, from %d to %d\n", ! 289: inet_ntoa(gate->sin_addr), rt->rt_metric, newmetric); ! 290: fflush(fd); ! 291: if (ferror(fd)) ! 292: traceoff(); ! 293: } ! 294: ! 295: dumpif(fd, ifp) ! 296: FILE *fd; ! 297: register struct interface *ifp; ! 298: { ! 299: if (ifp->int_input.ifd_count || ifp->int_output.ifd_count) { ! 300: fprintf(fd, "*** Packet history for interface %s ***\n", ! 301: ifp->int_name); ! 302: #ifdef notneeded ! 303: dumptrace(fd, "to", &ifp->int_output); ! 304: #endif ! 305: dumptrace(fd, "from", &ifp->int_input); ! 306: fprintf(fd, "*** end packet history ***\n"); ! 307: } ! 308: } ! 309: ! 310: dumptrace(fd, dir, ifd) ! 311: FILE *fd; ! 312: char *dir; ! 313: register struct ifdebug *ifd; ! 314: { ! 315: register struct iftrace *t; ! 316: char *cp = !strcmp(dir, "to") ? "Output" : "Input"; ! 317: ! 318: if (ifd->ifd_front == ifd->ifd_records && ! 319: ifd->ifd_front->ift_size == 0) { ! 320: fprintf(fd, "%s: no packets.\n", cp); ! 321: fflush(fd); ! 322: return; ! 323: } ! 324: fprintf(fd, "%s trace:\n", cp); ! 325: t = ifd->ifd_front - ifd->ifd_count; ! 326: if (t < ifd->ifd_records) ! 327: t += NRECORDS; ! 328: for ( ; ifd->ifd_count; ifd->ifd_count--, t++) { ! 329: if (t >= ifd->ifd_records + NRECORDS) ! 330: t = ifd->ifd_records; ! 331: if (t->ift_size == 0) ! 332: continue; ! 333: dumppacket(fd, dir, &t->ift_who, t->ift_packet, t->ift_size, ! 334: &t->ift_stamp); ! 335: } ! 336: } ! 337: ! 338: dumppacket(fd, dir, who, cp, size, stamp) ! 339: FILE *fd; ! 340: struct sockaddr_in *who; /* should be sockaddr */ ! 341: char *dir, *cp; ! 342: register int size; ! 343: struct timeval *stamp; ! 344: { ! 345: register struct rip *msg = (struct rip *)cp; ! 346: register struct netinfo *n; ! 347: ! 348: if (fd == NULL) ! 349: return; ! 350: if (msg->rip_cmd && msg->rip_cmd < RIPCMD_MAX) ! 351: fprintf(fd, "%s %s %s.%d %.19s:\n", ripcmds[msg->rip_cmd], ! 352: dir, inet_ntoa(who->sin_addr), ntohs(who->sin_port), ! 353: ctime((time_t *)&stamp->tv_sec)); ! 354: else { ! 355: fprintf(fd, "Bad cmd 0x%x %s %x.%d %.19s\n", msg->rip_cmd, ! 356: dir, inet_ntoa(who->sin_addr), ntohs(who->sin_port)); ! 357: fprintf(fd, "size=%d cp=%x packet=%x\n", size, cp, packet, ! 358: ctime((time_t *)&stamp->tv_sec)); ! 359: fflush(fd); ! 360: return; ! 361: } ! 362: if (tracepackets && tracecontents == 0) { ! 363: fflush(fd); ! 364: return; ! 365: } ! 366: switch (msg->rip_cmd) { ! 367: ! 368: case RIPCMD_REQUEST: ! 369: case RIPCMD_RESPONSE: ! 370: size -= 4 * sizeof (char); ! 371: n = msg->rip_nets; ! 372: for (; size > 0; n++, size -= sizeof (struct netinfo)) { ! 373: if (size < sizeof (struct netinfo)) { ! 374: fprintf(fd, "(truncated record, len %d)\n", ! 375: size); ! 376: break; ! 377: } ! 378: if (sizeof(n->rip_dst.sa_family) > 1) ! 379: n->rip_dst.sa_family = ntohs(n->rip_dst.sa_family); ! 380: ! 381: switch ((int)n->rip_dst.sa_family) { ! 382: ! 383: case AF_INET: ! 384: fprintf(fd, "\tdst %s metric %d\n", ! 385: #define satosin(sa) ((struct sockaddr_in *)&sa) ! 386: inet_ntoa(satosin(n->rip_dst)->sin_addr), ! 387: ntohl(n->rip_metric)); ! 388: break; ! 389: ! 390: default: ! 391: fprintf(fd, "\taf %d? metric %d\n", ! 392: n->rip_dst.sa_family, ! 393: ntohl(n->rip_metric)); ! 394: break; ! 395: } ! 396: } ! 397: break; ! 398: ! 399: case RIPCMD_TRACEON: ! 400: fprintf(fd, "\tfile=%*s\n", size, msg->rip_tracefile); ! 401: break; ! 402: ! 403: case RIPCMD_TRACEOFF: ! 404: break; ! 405: } ! 406: fflush(fd); ! 407: if (ferror(fd)) ! 408: traceoff(); ! 409: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.