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: }

Defined functions

dumpif defined in line 179; used 1 times
dumppacket defined in line 221; used 3 times
dumptrace defined in line 192; used 2 times
iftraceinit defined in line 35; used 2 times
trace defined in line 83; used 2 times
traceaction defined in line 115; used 1 times
traceinit defined in line 24; used 1 times
traceoff defined in line 73; used 1 times
traceon defined in line 56; used 2 times

Defined variables

sccsid defined in line 8; never used
tracing defined in line 21; used 4 times

Defined struct's

bits defined in line 121; used 2 times
  • in line 139(2)

Defined macros

NRECORDS defined in line 18; used 6 times
RIPCMDS defined in line 14; never used
satosin defined in line 251; used 1 times
Last modified: 1986-05-30
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1780
Valid CSS Valid XHTML 1.0 Strict