1*24316Ssklower #ifndef lint 2*24316Ssklower static char sccsid[] = "@(#)trace.c 4.6 (Berkeley) 4/9/84"; 3*24316Ssklower #endif 4*24316Ssklower 5*24316Ssklower /* 6*24316Ssklower * Routing Table Management Daemon 7*24316Ssklower */ 8*24316Ssklower #define RIPCMDS 9*24316Ssklower #include "defs.h" 10*24316Ssklower 11*24316Ssklower #define NRECORDS 50 /* size of circular trace buffer */ 12*24316Ssklower #ifdef DEBUG 13*24316Ssklower FILE *ftrace = stdout; 14*24316Ssklower int tracing = 1; 15*24316Ssklower #endif 16*24316Ssklower 17*24316Ssklower char *xns_ntoa(); 18*24316Ssklower 19*24316Ssklower traceinit(ifp) 20*24316Ssklower register struct interface *ifp; 21*24316Ssklower { 22*24316Ssklower 23*24316Ssklower if (iftraceinit(ifp, &ifp->int_input) && 24*24316Ssklower iftraceinit(ifp, &ifp->int_output)) 25*24316Ssklower return; 26*24316Ssklower tracing = 0; 27*24316Ssklower fprintf(stderr, "traceinit: can't init %s\n", ifp->int_name); 28*24316Ssklower } 29*24316Ssklower 30*24316Ssklower static 31*24316Ssklower iftraceinit(ifp, ifd) 32*24316Ssklower struct interface *ifp; 33*24316Ssklower register struct ifdebug *ifd; 34*24316Ssklower { 35*24316Ssklower register struct iftrace *t; 36*24316Ssklower 37*24316Ssklower ifd->ifd_records = 38*24316Ssklower (struct iftrace *)malloc(NRECORDS * sizeof (struct iftrace)); 39*24316Ssklower if (ifd->ifd_records == 0) 40*24316Ssklower return (0); 41*24316Ssklower ifd->ifd_front = ifd->ifd_records; 42*24316Ssklower ifd->ifd_count = 0; 43*24316Ssklower for (t = ifd->ifd_records; t < ifd->ifd_records + NRECORDS; t++) { 44*24316Ssklower t->ift_size = 0; 45*24316Ssklower t->ift_packet = 0; 46*24316Ssklower } 47*24316Ssklower ifd->ifd_if = ifp; 48*24316Ssklower return (1); 49*24316Ssklower } 50*24316Ssklower 51*24316Ssklower traceon(file) 52*24316Ssklower char *file; 53*24316Ssklower { 54*24316Ssklower 55*24316Ssklower if (ftrace != NULL) 56*24316Ssklower return; 57*24316Ssklower ftrace = fopen(file, "a"); 58*24316Ssklower if (ftrace == NULL) 59*24316Ssklower return; 60*24316Ssklower dup2(fileno(ftrace), 1); 61*24316Ssklower dup2(fileno(ftrace), 2); 62*24316Ssklower tracing = 1; 63*24316Ssklower } 64*24316Ssklower 65*24316Ssklower traceoff() 66*24316Ssklower { 67*24316Ssklower if (!tracing) 68*24316Ssklower return; 69*24316Ssklower if (ftrace != NULL) 70*24316Ssklower fclose(ftrace); 71*24316Ssklower ftrace = NULL; 72*24316Ssklower tracing = 0; 73*24316Ssklower } 74*24316Ssklower 75*24316Ssklower trace(ifd, who, p, len, m) 76*24316Ssklower register struct ifdebug *ifd; 77*24316Ssklower struct sockaddr *who; 78*24316Ssklower char *p; 79*24316Ssklower int len, m; 80*24316Ssklower { 81*24316Ssklower register struct iftrace *t; 82*24316Ssklower 83*24316Ssklower if (ifd->ifd_records == 0) 84*24316Ssklower return; 85*24316Ssklower t = ifd->ifd_front++; 86*24316Ssklower if (ifd->ifd_front >= ifd->ifd_records + NRECORDS) 87*24316Ssklower ifd->ifd_front = ifd->ifd_records; 88*24316Ssklower if (ifd->ifd_count < NRECORDS) 89*24316Ssklower ifd->ifd_count++; 90*24316Ssklower if (t->ift_size > 0 && t->ift_packet) 91*24316Ssklower free(t->ift_packet); 92*24316Ssklower t->ift_packet = 0; 93*24316Ssklower t->ift_stamp = time(0); 94*24316Ssklower t->ift_who = *who; 95*24316Ssklower if (len > 0) { 96*24316Ssklower t->ift_packet = malloc(len); 97*24316Ssklower if (t->ift_packet) 98*24316Ssklower bcopy(p, t->ift_packet, len); 99*24316Ssklower else 100*24316Ssklower len = 0; 101*24316Ssklower } 102*24316Ssklower t->ift_size = len; 103*24316Ssklower t->ift_metric = m; 104*24316Ssklower } 105*24316Ssklower 106*24316Ssklower traceaction(fd, action, rt) 107*24316Ssklower FILE *fd; 108*24316Ssklower char *action; 109*24316Ssklower struct rt_entry *rt; 110*24316Ssklower { 111*24316Ssklower struct sockaddr_xn *dst, *gate; 112*24316Ssklower static struct bits { 113*24316Ssklower int t_bits; 114*24316Ssklower char *t_name; 115*24316Ssklower } flagbits[] = { 116*24316Ssklower { RTF_UP, "UP" }, 117*24316Ssklower { RTF_GATEWAY, "GATEWAY" }, 118*24316Ssklower { RTF_HOST, "HOST" }, 119*24316Ssklower { 0 } 120*24316Ssklower }, statebits[] = { 121*24316Ssklower { RTS_PASSIVE, "PASSIVE" }, 122*24316Ssklower { RTS_REMOTE, "REMOTE" }, 123*24316Ssklower { RTS_INTERFACE,"INTERFACE" }, 124*24316Ssklower { RTS_CHANGED, "CHANGED" }, 125*24316Ssklower { 0 } 126*24316Ssklower }; 127*24316Ssklower register struct bits *p; 128*24316Ssklower register int first; 129*24316Ssklower char *cp; 130*24316Ssklower struct interface *ifp; 131*24316Ssklower 132*24316Ssklower if (fd == NULL) 133*24316Ssklower return; 134*24316Ssklower fprintf(fd, "%s ", action); 135*24316Ssklower dst = (struct sockaddr_xn *)&rt->rt_dst; 136*24316Ssklower gate = (struct sockaddr_xn *)&rt->rt_router; 137*24316Ssklower fprintf(fd, "dst %s, ", xns_ntoa(&dst->sxn_addr)); 138*24316Ssklower fprintf(fd, "router %s, metric %d, flags", 139*24316Ssklower xns_ntoa(&gate->sxn_addr), rt->rt_metric); 140*24316Ssklower cp = " %s"; 141*24316Ssklower for (first = 1, p = flagbits; p->t_bits > 0; p++) { 142*24316Ssklower if ((rt->rt_flags & p->t_bits) == 0) 143*24316Ssklower continue; 144*24316Ssklower fprintf(fd, cp, p->t_name); 145*24316Ssklower if (first) { 146*24316Ssklower cp = "|%s"; 147*24316Ssklower first = 0; 148*24316Ssklower } 149*24316Ssklower } 150*24316Ssklower fprintf(fd, " state"); 151*24316Ssklower cp = " %s"; 152*24316Ssklower for (first = 1, p = statebits; p->t_bits > 0; p++) { 153*24316Ssklower if ((rt->rt_state & p->t_bits) == 0) 154*24316Ssklower continue; 155*24316Ssklower fprintf(fd, cp, p->t_name); 156*24316Ssklower if (first) { 157*24316Ssklower cp = "|%s"; 158*24316Ssklower first = 0; 159*24316Ssklower } 160*24316Ssklower } 161*24316Ssklower putc('\n', fd); 162*24316Ssklower if (!tracepackets && (rt->rt_state & RTS_PASSIVE) == 0 && rt->rt_ifp) 163*24316Ssklower dumpif(fd, rt->rt_ifp); 164*24316Ssklower fflush(fd); 165*24316Ssklower } 166*24316Ssklower 167*24316Ssklower dumpif(fd, ifp) 168*24316Ssklower register struct interface *ifp; 169*24316Ssklower { 170*24316Ssklower if (ifp->int_input.ifd_count || ifp->int_output.ifd_count) { 171*24316Ssklower fprintf(fd, "*** Packet history for interface %s ***\n", 172*24316Ssklower ifp->int_name); 173*24316Ssklower dumptrace(fd, "to", &ifp->int_output); 174*24316Ssklower dumptrace(fd, "from", &ifp->int_input); 175*24316Ssklower fprintf(fd, "*** end packet history ***\n"); 176*24316Ssklower } 177*24316Ssklower } 178*24316Ssklower 179*24316Ssklower dumptrace(fd, dir, ifd) 180*24316Ssklower FILE *fd; 181*24316Ssklower char *dir; 182*24316Ssklower register struct ifdebug *ifd; 183*24316Ssklower { 184*24316Ssklower register struct iftrace *t; 185*24316Ssklower char *cp = !strcmp(dir, "to") ? "Output" : "Input"; 186*24316Ssklower 187*24316Ssklower if (ifd->ifd_front == ifd->ifd_records && 188*24316Ssklower ifd->ifd_front->ift_size == 0) { 189*24316Ssklower fprintf(fd, "%s: no packets.\n", cp); 190*24316Ssklower return; 191*24316Ssklower } 192*24316Ssklower fprintf(fd, "%s trace:\n", cp); 193*24316Ssklower t = ifd->ifd_front - ifd->ifd_count; 194*24316Ssklower if (t < ifd->ifd_records) 195*24316Ssklower t += NRECORDS; 196*24316Ssklower for ( ; ifd->ifd_count; ifd->ifd_count--, t++) { 197*24316Ssklower if (t >= ifd->ifd_records + NRECORDS) 198*24316Ssklower t = ifd->ifd_records; 199*24316Ssklower if (t->ift_size == 0) 200*24316Ssklower continue; 201*24316Ssklower fprintf(fd, "%.24s: metric=%d\n", ctime(&t->ift_stamp), 202*24316Ssklower t->ift_metric); 203*24316Ssklower dumppacket(fd, dir, &t->ift_who, t->ift_packet, t->ift_size); 204*24316Ssklower } 205*24316Ssklower } 206*24316Ssklower 207*24316Ssklower dumppacket(fd, dir, who, cp, size) 208*24316Ssklower FILE *fd; 209*24316Ssklower struct sockaddr_xn *who; /* should be sockaddr */ 210*24316Ssklower char *dir, *cp; 211*24316Ssklower register int size; 212*24316Ssklower { 213*24316Ssklower register struct rip *msg = (struct rip *)cp; 214*24316Ssklower register struct netinfo *n; 215*24316Ssklower 216*24316Ssklower if (msg->rip_cmd && ntohs(msg->rip_cmd) < RIPCMD_MAX) 217*24316Ssklower fprintf(fd, "%s %s %s#%x", ripcmds[ntohs(msg->rip_cmd)], 218*24316Ssklower dir, xns_ntoa(&who->sxn_addr), ntohs(who->sxn_addr.xn_socket)); 219*24316Ssklower else { 220*24316Ssklower fprintf(fd, "Bad cmd 0x%x %s %s#%x\n", ntohs(msg->rip_cmd), 221*24316Ssklower dir, xns_ntoa(&who->sxn_addr), ntohs(who->sxn_addr.xn_socket)); 222*24316Ssklower fprintf(fd, "size=%d cp=%x packet=%x\n", size, cp, packet); 223*24316Ssklower return; 224*24316Ssklower } 225*24316Ssklower switch (ntohs(msg->rip_cmd)) { 226*24316Ssklower 227*24316Ssklower case RIPCMD_REQUEST: 228*24316Ssklower case RIPCMD_RESPONSE: 229*24316Ssklower fprintf(fd, ":\n"); 230*24316Ssklower size -= sizeof (u_short); 231*24316Ssklower n = msg->rip_nets; 232*24316Ssklower for (; size > 0; n++, size -= sizeof (struct netinfo)) { 233*24316Ssklower if (size < sizeof (struct netinfo)) 234*24316Ssklower break; 235*24316Ssklower fprintf(fd, "\tnet %#x metric %d\n", 236*24316Ssklower ntohl(xnnet(n->rip_dst)), 237*24316Ssklower ntohs(n->rip_metric)); 238*24316Ssklower } 239*24316Ssklower break; 240*24316Ssklower 241*24316Ssklower } 242*24316Ssklower } 243*24316Ssklower 244*24316Ssklower char * 245*24316Ssklower xns_ntoa(addr) 246*24316Ssklower struct xn_addr *addr; 247*24316Ssklower { 248*24316Ssklower static char buf[100]; 249*24316Ssklower 250*24316Ssklower sprintf(buf, "%x#%x:%x:%x:%x:%x:%x", 251*24316Ssklower ntohl(xnnet(addr->xn_net)), 252*24316Ssklower addr->xn_host[0], addr->xn_host[1], 253*24316Ssklower addr->xn_host[2], addr->xn_host[3], 254*24316Ssklower addr->xn_host[4], addr->xn_host[5]); 255*24316Ssklower 256*24316Ssklower return(buf); 257*24316Ssklower } 258