X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/f036a54db3960d8ae9ef89e54b9823c268c44ebc..7abf8d658566ec3a7bd87dcb4b2d9b0902ffd507:/usr/src/sbin/routed/trace.c?ds=sidebyside diff --git a/usr/src/sbin/routed/trace.c b/usr/src/sbin/routed/trace.c index 5411730425..7f6fdc3ebf 100644 --- a/usr/src/sbin/routed/trace.c +++ b/usr/src/sbin/routed/trace.c @@ -1,18 +1,41 @@ +/* + * Copyright (c) 1983, 1988 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + #ifndef lint -static char sccsid[] = "@(#)trace.c 4.1 %G%"; -#endif +static char sccsid[] = "@(#)trace.c 5.9 (Berkeley) %G%"; +#endif /* not lint */ /* * Routing Table Management Daemon */ #define RIPCMDS -#include "router.h" +#include "defs.h" +#include +#include +#include +#include "pathnames.h" #define NRECORDS 50 /* size of circular trace buffer */ #ifdef DEBUG FILE *ftrace = stdout; -int tracing = 1; +int traceactions = 0; #endif +static struct timeval lastlog; +static char *savetracename; traceinit(ifp) register struct interface *ifp; @@ -21,7 +44,7 @@ traceinit(ifp) if (iftraceinit(ifp, &ifp->int_input) && iftraceinit(ifp, &ifp->int_output)) return; - tracing = 0; + tracehistory = 0; fprintf(stderr, "traceinit: can't init %s\n", ifp->int_name); } @@ -37,6 +60,7 @@ iftraceinit(ifp, ifd) if (ifd->ifd_records == 0) return (0); ifd->ifd_front = ifd->ifd_records; + ifd->ifd_count = 0; for (t = ifd->ifd_records; t < ifd->ifd_records + NRECORDS; t++) { t->ift_size = 0; t->ift_packet = 0; @@ -48,25 +72,96 @@ iftraceinit(ifp, ifd) traceon(file) char *file; { + struct stat stbuf; if (ftrace != NULL) return; + if (stat(file, &stbuf) >= 0 && (stbuf.st_mode & S_IFMT) != S_IFREG) + return; + savetracename = file; + (void) gettimeofday(&now, (struct timezone *)NULL); ftrace = fopen(file, "a"); if (ftrace == NULL) return; dup2(fileno(ftrace), 1); dup2(fileno(ftrace), 2); - tracing = 1; + traceactions = 1; + fprintf(ftrace, "Tracing enabled %s\n", ctime((time_t *)&now.tv_sec)); } traceoff() { - if (!tracing) + if (!traceactions) return; - if (ftrace != NULL) + if (ftrace != NULL) { + int fd = open(_PATH_DEVNULL, O_RDWR); + + fprintf(ftrace, "Tracing disabled %s\n", + ctime((time_t *)&now.tv_sec)); + fflush(ftrace); + (void) dup2(fd, 1); + (void) dup2(fd, 2); + (void) close(fd); fclose(ftrace); - ftrace = NULL; - tracing = 0; + ftrace = NULL; + } + traceactions = 0; + tracehistory = 0; + tracepackets = 0; + tracecontents = 0; +} + +sigtrace(s) + int s; +{ + + if (s == SIGUSR2) + traceoff(); + else if (ftrace == NULL && savetracename) + traceon(savetracename); + else + bumploglevel(); +} + +/* + * Move to next higher level of tracing when -t option processed or + * SIGUSR1 is received. Successive levels are: + * traceactions + * traceactions + tracepackets + * traceactions + tracehistory (packets and contents after change) + * traceactions + tracepackets + tracecontents + */ +bumploglevel() +{ + + (void) gettimeofday(&now, (struct timezone *)NULL); + if (traceactions == 0) { + traceactions++; + if (ftrace) + fprintf(ftrace, "Tracing actions started %s\n", + ctime((time_t *)&now.tv_sec)); + } else if (tracepackets == 0) { + tracepackets++; + tracehistory = 0; + tracecontents = 0; + if (ftrace) + fprintf(ftrace, "Tracing packets started %s\n", + ctime((time_t *)&now.tv_sec)); + } else if (tracehistory == 0) { + tracehistory++; + if (ftrace) + fprintf(ftrace, "Tracing history started %s\n", + ctime((time_t *)&now.tv_sec)); + } else { + tracepackets++; + tracecontents++; + tracehistory = 0; + if (ftrace) + fprintf(ftrace, "Tracing packet contents started %s\n", + ctime((time_t *)&now.tv_sec)); + } + if (ftrace) + fflush(ftrace); } trace(ifd, who, p, len, m) @@ -82,18 +177,21 @@ trace(ifd, who, p, len, m) t = ifd->ifd_front++; if (ifd->ifd_front >= ifd->ifd_records + NRECORDS) ifd->ifd_front = ifd->ifd_records; - if (t->ift_size > 0 && t->ift_packet) + if (ifd->ifd_count < NRECORDS) + ifd->ifd_count++; + if (t->ift_size > 0 && t->ift_size < len && t->ift_packet) { free(t->ift_packet); - t->ift_packet = 0; - t->ift_stamp = time(0); + t->ift_packet = 0; + } + t->ift_stamp = now; t->ift_who = *who; - if (len > 0) { + if (len > 0 && t->ift_packet == 0) { t->ift_packet = malloc(len); - if (t->ift_packet) - bcopy(p, t->ift_packet, len); - else + if (t->ift_packet == 0) len = 0; } + if (len > 0) + bcopy(p, t->ift_packet, len); t->ift_size = len; t->ift_metric = m; } @@ -117,6 +215,9 @@ traceaction(fd, action, rt) { RTS_REMOTE, "REMOTE" }, { RTS_INTERFACE,"INTERFACE" }, { RTS_CHANGED, "CHANGED" }, + { RTS_INTERNAL, "INTERNAL" }, + { RTS_EXTERNAL, "EXTERNAL" }, + { RTS_SUBNET, "SUBNET" }, { 0 } }; register struct bits *p; @@ -126,11 +227,16 @@ traceaction(fd, action, rt) if (fd == NULL) return; + if (lastlog.tv_sec != now.tv_sec || lastlog.tv_usec != now.tv_usec) { + fprintf(fd, "\n%.19s:\n", ctime((time_t *)&now.tv_sec)); + lastlog = now; + } fprintf(fd, "%s ", action); dst = (struct sockaddr_in *)&rt->rt_dst; gate = (struct sockaddr_in *)&rt->rt_router; - fprintf(fd, "dst %x, router %x, metric %d, flags", dst->sin_addr, - gate->sin_addr, rt->rt_metric); + fprintf(fd, "dst %s, ", inet_ntoa(dst->sin_addr)); + fprintf(fd, "router %s, metric %d, flags", + inet_ntoa(gate->sin_addr), rt->rt_metric); cp = " %s"; for (first = 1, p = flagbits; p->t_bits > 0; p++) { if ((rt->rt_flags & p->t_bits) == 0) @@ -152,22 +258,51 @@ traceaction(fd, action, rt) first = 0; } } - putc('\n', fd); - if ((rt->rt_state & RTS_PASSIVE) == 0 && rt->rt_ifp) + fprintf(fd, " timer %d\n", rt->rt_timer); + if (tracehistory && !tracepackets && + (rt->rt_state & RTS_PASSIVE) == 0 && rt->rt_ifp) dumpif(fd, rt->rt_ifp); fflush(fd); + if (ferror(fd)) + traceoff(); +} + +tracenewmetric(fd, rt, newmetric) + FILE *fd; + struct rt_entry *rt; + int newmetric; +{ + struct sockaddr_in *dst, *gate; + + if (fd == NULL) + return; + if (lastlog.tv_sec != now.tv_sec || lastlog.tv_usec != now.tv_usec) { + fprintf(fd, "\n%.19s:\n", ctime((time_t *)&now.tv_sec)); + lastlog = now; + } + dst = (struct sockaddr_in *)&rt->rt_dst; + gate = (struct sockaddr_in *)&rt->rt_router; + fprintf(fd, "CHANGE metric dst %s, ", inet_ntoa(dst->sin_addr)); + fprintf(fd, "router %s, from %d to %d\n", + inet_ntoa(gate->sin_addr), rt->rt_metric, newmetric); + fflush(fd); + if (ferror(fd)) + traceoff(); } dumpif(fd, ifp) + FILE *fd; register struct interface *ifp; { - register struct ifdebug *ifd; - - fprintf(fd, "*** Packet history for interface %s ***\n", - ifp->int_name); - dumptrace(fd, "to", &ifp->int_output); - dumptrace(fd, "from", &ifp->int_output); - fprintf(fd, "*** end packet history ***\n"); + if (ifp->int_input.ifd_count || ifp->int_output.ifd_count) { + fprintf(fd, "*** Packet history for interface %s ***\n", + ifp->int_name); +#ifdef notneeded + dumptrace(fd, "to", &ifp->int_output); +#endif + dumptrace(fd, "from", &ifp->int_input); + fprintf(fd, "*** end packet history ***\n"); + } } dumptrace(fd, dir, ifd) @@ -181,65 +316,92 @@ dumptrace(fd, dir, ifd) if (ifd->ifd_front == ifd->ifd_records && ifd->ifd_front->ift_size == 0) { fprintf(fd, "%s: no packets.\n", cp); + fflush(fd); return; } fprintf(fd, "%s trace:\n", cp); - for (t = ifd->ifd_front; t <= ifd->ifd_records + NRECORDS; t++) { + t = ifd->ifd_front - ifd->ifd_count; + if (t < ifd->ifd_records) + t += NRECORDS; + for ( ; ifd->ifd_count; ifd->ifd_count--, t++) { + if (t >= ifd->ifd_records + NRECORDS) + t = ifd->ifd_records; if (t->ift_size == 0) continue; - fprintf(fd, "%.24s: metric=%d\n", ctime(&t->ift_stamp), - t->ift_metric); - dumppacket(fd, dir, &t->ift_who, t->ift_packet, t->ift_size); - } - for (t = ifd->ifd_records; t < ifd->ifd_front; t++) { - if (t->ift_size == 0) - continue; - fprintf(fd, "%.24s: metric=%d\n", ctime(&t->ift_stamp), - t->ift_metric); - dumppacket(fd, dir, &t->ift_who, t->ift_packet, t->ift_size); + dumppacket(fd, dir, &t->ift_who, t->ift_packet, t->ift_size, + &t->ift_stamp); } } -dumppacket(fd, dir, who, cp, size) +dumppacket(fd, dir, who, cp, size, stamp) FILE *fd; struct sockaddr_in *who; /* should be sockaddr */ char *dir, *cp; register int size; + struct timeval *stamp; { register struct rip *msg = (struct rip *)cp; register struct netinfo *n; + if (fd == NULL) + return; if (msg->rip_cmd && msg->rip_cmd < RIPCMD_MAX) - fprintf(fd, "%s %s %x.%d", ripcmds[msg->rip_cmd], - dir, who->sin_addr, ntohs(who->sin_port)); + fprintf(fd, "%s %s %s.%d %.19s:\n", ripcmds[msg->rip_cmd], + dir, inet_ntoa(who->sin_addr), ntohs(who->sin_port), + ctime((time_t *)&stamp->tv_sec)); else { - fprintf(fd, "Bad cmd 0x%x %s %x.%d\n", msg->rip_cmd, - dir, who->sin_addr, ntohs(who->sin_port)); - fprintf(fd, "size=%d cp=%x packet=%x\n", size, cp, packet); + fprintf(fd, "Bad cmd 0x%x %s %x.%d %.19s\n", msg->rip_cmd, + dir, inet_ntoa(who->sin_addr), ntohs(who->sin_port)); + fprintf(fd, "size=%d cp=%x packet=%x\n", size, cp, packet, + ctime((time_t *)&stamp->tv_sec)); + fflush(fd); + return; + } + if (tracepackets && tracecontents == 0) { + fflush(fd); return; } switch (msg->rip_cmd) { case RIPCMD_REQUEST: case RIPCMD_RESPONSE: - fprintf(fd, ":\n"); size -= 4 * sizeof (char); n = msg->rip_nets; for (; size > 0; n++, size -= sizeof (struct netinfo)) { - if (size < sizeof (struct netinfo)) + if (size < sizeof (struct netinfo)) { + fprintf(fd, "(truncated record, len %d)\n", + size); break; - fprintf(fd, "\tdst %x metric %d\n", - ((struct sockaddr_in *)&n->rip_dst)->sin_addr, - n->rip_metric); + } + if (sizeof(n->rip_dst.sa_family) > 1) + n->rip_dst.sa_family = ntohs(n->rip_dst.sa_family); + + switch ((int)n->rip_dst.sa_family) { + + case AF_INET: + fprintf(fd, "\tdst %s metric %d\n", +#define satosin(sa) ((struct sockaddr_in *)&sa) + inet_ntoa(satosin(n->rip_dst)->sin_addr), + ntohl(n->rip_metric)); + break; + + default: + fprintf(fd, "\taf %d? metric %d\n", + n->rip_dst.sa_family, + ntohl(n->rip_metric)); + break; + } } break; case RIPCMD_TRACEON: - fprintf(fd, ", file=%*s\n", size, msg->rip_tracefile); + fprintf(fd, "\tfile=%*s\n", size, msg->rip_tracefile); break; case RIPCMD_TRACEOFF: - fprintf(fd, "\n"); break; } + fflush(fd); + if (ferror(fd)) + traceoff(); }