122001Sdist /* 222001Sdist * Copyright (c) 1983 Regents of the University of California. 322001Sdist * All rights reserved. The Berkeley software License Agreement 422001Sdist * specifies the terms and conditions for redistribution. 522001Sdist */ 622001Sdist 79022Ssam #ifndef lint 8*26960Skarels static char sccsid[] = "@(#)trace.c 5.2 (Berkeley) 03/28/86"; 922001Sdist #endif not lint 109022Ssam 119022Ssam /* 129022Ssam * Routing Table Management Daemon 139022Ssam */ 149022Ssam #define RIPCMDS 1510245Ssam #include "defs.h" 169022Ssam 179022Ssam #define NRECORDS 50 /* size of circular trace buffer */ 189022Ssam #ifdef DEBUG 199022Ssam FILE *ftrace = stdout; 209022Ssam int tracing = 1; 219022Ssam #endif 229022Ssam 239022Ssam traceinit(ifp) 249022Ssam register struct interface *ifp; 259022Ssam { 269022Ssam 279022Ssam if (iftraceinit(ifp, &ifp->int_input) && 289022Ssam iftraceinit(ifp, &ifp->int_output)) 299022Ssam return; 309022Ssam tracing = 0; 319022Ssam fprintf(stderr, "traceinit: can't init %s\n", ifp->int_name); 329022Ssam } 339022Ssam 349022Ssam static 359022Ssam iftraceinit(ifp, ifd) 369022Ssam struct interface *ifp; 379022Ssam register struct ifdebug *ifd; 389022Ssam { 399022Ssam register struct iftrace *t; 409022Ssam 419022Ssam ifd->ifd_records = 429022Ssam (struct iftrace *)malloc(NRECORDS * sizeof (struct iftrace)); 439022Ssam if (ifd->ifd_records == 0) 449022Ssam return (0); 459022Ssam ifd->ifd_front = ifd->ifd_records; 4616314Skarels ifd->ifd_count = 0; 479022Ssam for (t = ifd->ifd_records; t < ifd->ifd_records + NRECORDS; t++) { 489022Ssam t->ift_size = 0; 499022Ssam t->ift_packet = 0; 509022Ssam } 519022Ssam ifd->ifd_if = ifp; 529022Ssam return (1); 539022Ssam } 549022Ssam 559022Ssam traceon(file) 569022Ssam char *file; 579022Ssam { 589022Ssam 599022Ssam if (ftrace != NULL) 609022Ssam return; 619022Ssam ftrace = fopen(file, "a"); 629022Ssam if (ftrace == NULL) 639022Ssam return; 649022Ssam dup2(fileno(ftrace), 1); 659022Ssam dup2(fileno(ftrace), 2); 669022Ssam tracing = 1; 679022Ssam } 689022Ssam 699022Ssam traceoff() 709022Ssam { 719022Ssam if (!tracing) 729022Ssam return; 739022Ssam if (ftrace != NULL) 749022Ssam fclose(ftrace); 759022Ssam ftrace = NULL; 769022Ssam tracing = 0; 779022Ssam } 789022Ssam 799022Ssam trace(ifd, who, p, len, m) 809022Ssam register struct ifdebug *ifd; 819022Ssam struct sockaddr *who; 829022Ssam char *p; 839022Ssam int len, m; 849022Ssam { 859022Ssam register struct iftrace *t; 869022Ssam 879022Ssam if (ifd->ifd_records == 0) 889022Ssam return; 899022Ssam t = ifd->ifd_front++; 909022Ssam if (ifd->ifd_front >= ifd->ifd_records + NRECORDS) 919022Ssam ifd->ifd_front = ifd->ifd_records; 9216314Skarels if (ifd->ifd_count < NRECORDS) 9316314Skarels ifd->ifd_count++; 94*26960Skarels if (t->ift_size > 0 && t->ift_size < len && t->ift_packet) { 959022Ssam free(t->ift_packet); 96*26960Skarels t->ift_packet = 0; 97*26960Skarels } 989022Ssam t->ift_stamp = time(0); 999022Ssam t->ift_who = *who; 100*26960Skarels if (len > 0 && t->ift_packet == 0) { 1019022Ssam t->ift_packet = malloc(len); 102*26960Skarels if (t->ift_packet == 0) 1039022Ssam len = 0; 1049022Ssam } 105*26960Skarels if (len > 0) 106*26960Skarels bcopy(p, t->ift_packet, len); 1079022Ssam t->ift_size = len; 1089022Ssam t->ift_metric = m; 1099022Ssam } 1109022Ssam 1119022Ssam traceaction(fd, action, rt) 1129022Ssam FILE *fd; 1139022Ssam char *action; 1149022Ssam struct rt_entry *rt; 1159022Ssam { 1169022Ssam struct sockaddr_in *dst, *gate; 1179022Ssam static struct bits { 1189022Ssam int t_bits; 1199022Ssam char *t_name; 1209022Ssam } flagbits[] = { 1219022Ssam { RTF_UP, "UP" }, 1229022Ssam { RTF_GATEWAY, "GATEWAY" }, 1239022Ssam { RTF_HOST, "HOST" }, 1249022Ssam { 0 } 1259022Ssam }, statebits[] = { 1269022Ssam { RTS_PASSIVE, "PASSIVE" }, 1279022Ssam { RTS_REMOTE, "REMOTE" }, 1289022Ssam { RTS_INTERFACE,"INTERFACE" }, 1299022Ssam { RTS_CHANGED, "CHANGED" }, 1309022Ssam { 0 } 1319022Ssam }; 1329022Ssam register struct bits *p; 1339022Ssam register int first; 1349022Ssam char *cp; 1359022Ssam struct interface *ifp; 1369022Ssam 1379022Ssam if (fd == NULL) 1389022Ssam return; 1399022Ssam fprintf(fd, "%s ", action); 1409022Ssam dst = (struct sockaddr_in *)&rt->rt_dst; 1419022Ssam gate = (struct sockaddr_in *)&rt->rt_router; 14215099Ssam fprintf(fd, "dst %s, ", inet_ntoa(dst->sin_addr)); 14315099Ssam fprintf(fd, "router %s, metric %d, flags", 14415099Ssam inet_ntoa(gate->sin_addr), rt->rt_metric); 1459022Ssam cp = " %s"; 1469022Ssam for (first = 1, p = flagbits; p->t_bits > 0; p++) { 1479022Ssam if ((rt->rt_flags & p->t_bits) == 0) 1489022Ssam continue; 1499022Ssam fprintf(fd, cp, p->t_name); 1509022Ssam if (first) { 1519022Ssam cp = "|%s"; 1529022Ssam first = 0; 1539022Ssam } 1549022Ssam } 1559022Ssam fprintf(fd, " state"); 1569022Ssam cp = " %s"; 1579022Ssam for (first = 1, p = statebits; p->t_bits > 0; p++) { 1589022Ssam if ((rt->rt_state & p->t_bits) == 0) 1599022Ssam continue; 1609022Ssam fprintf(fd, cp, p->t_name); 1619022Ssam if (first) { 1629022Ssam cp = "|%s"; 1639022Ssam first = 0; 1649022Ssam } 1659022Ssam } 1669022Ssam putc('\n', fd); 16716128Skarels if (!tracepackets && (rt->rt_state & RTS_PASSIVE) == 0 && rt->rt_ifp) 1689022Ssam dumpif(fd, rt->rt_ifp); 1699022Ssam fflush(fd); 1709022Ssam } 1719022Ssam 1729022Ssam dumpif(fd, ifp) 1739022Ssam register struct interface *ifp; 1749022Ssam { 17516314Skarels if (ifp->int_input.ifd_count || ifp->int_output.ifd_count) { 17616314Skarels fprintf(fd, "*** Packet history for interface %s ***\n", 17716314Skarels ifp->int_name); 17816314Skarels dumptrace(fd, "to", &ifp->int_output); 17916314Skarels dumptrace(fd, "from", &ifp->int_input); 18016314Skarels fprintf(fd, "*** end packet history ***\n"); 18116314Skarels } 182*26960Skarels fflush(fd); 1839022Ssam } 1849022Ssam 1859022Ssam dumptrace(fd, dir, ifd) 1869022Ssam FILE *fd; 1879022Ssam char *dir; 1889022Ssam register struct ifdebug *ifd; 1899022Ssam { 1909022Ssam register struct iftrace *t; 1919022Ssam char *cp = !strcmp(dir, "to") ? "Output" : "Input"; 1929022Ssam 1939022Ssam if (ifd->ifd_front == ifd->ifd_records && 1949022Ssam ifd->ifd_front->ift_size == 0) { 1959022Ssam fprintf(fd, "%s: no packets.\n", cp); 196*26960Skarels fflush(fd); 1979022Ssam return; 1989022Ssam } 1999022Ssam fprintf(fd, "%s trace:\n", cp); 20016314Skarels t = ifd->ifd_front - ifd->ifd_count; 20116314Skarels if (t < ifd->ifd_records) 20216314Skarels t += NRECORDS; 20316314Skarels for ( ; ifd->ifd_count; ifd->ifd_count--, t++) { 20416314Skarels if (t >= ifd->ifd_records + NRECORDS) 20516314Skarels t = ifd->ifd_records; 2069022Ssam if (t->ift_size == 0) 2079022Ssam continue; 2089022Ssam fprintf(fd, "%.24s: metric=%d\n", ctime(&t->ift_stamp), 2099022Ssam t->ift_metric); 2109022Ssam dumppacket(fd, dir, &t->ift_who, t->ift_packet, t->ift_size); 2119022Ssam } 2129022Ssam } 2139022Ssam 2149022Ssam dumppacket(fd, dir, who, cp, size) 2159022Ssam FILE *fd; 2169022Ssam struct sockaddr_in *who; /* should be sockaddr */ 2179022Ssam char *dir, *cp; 2189022Ssam register int size; 2199022Ssam { 2209022Ssam register struct rip *msg = (struct rip *)cp; 2219022Ssam register struct netinfo *n; 2229022Ssam 2239022Ssam if (msg->rip_cmd && msg->rip_cmd < RIPCMD_MAX) 22415099Ssam fprintf(fd, "%s %s %s.%d", ripcmds[msg->rip_cmd], 22515099Ssam dir, inet_ntoa(who->sin_addr), ntohs(who->sin_port)); 2269022Ssam else { 2279022Ssam fprintf(fd, "Bad cmd 0x%x %s %x.%d\n", msg->rip_cmd, 22815099Ssam dir, inet_ntoa(who->sin_addr), ntohs(who->sin_port)); 2299022Ssam fprintf(fd, "size=%d cp=%x packet=%x\n", size, cp, packet); 230*26960Skarels fflush(fd); 2319022Ssam return; 2329022Ssam } 2339022Ssam switch (msg->rip_cmd) { 2349022Ssam 2359022Ssam case RIPCMD_REQUEST: 2369022Ssam case RIPCMD_RESPONSE: 2379022Ssam fprintf(fd, ":\n"); 2389022Ssam size -= 4 * sizeof (char); 2399022Ssam n = msg->rip_nets; 2409022Ssam for (; size > 0; n++, size -= sizeof (struct netinfo)) { 2419022Ssam if (size < sizeof (struct netinfo)) 2429022Ssam break; 24315099Ssam fprintf(fd, "\tdst %s metric %d\n", 24415099Ssam #define satosin(sa) ((struct sockaddr_in *)&sa) 24515099Ssam inet_ntoa(satosin(n->rip_dst)->sin_addr), 24615099Ssam ntohl(n->rip_metric)); 2479022Ssam } 2489022Ssam break; 2499022Ssam 2509022Ssam case RIPCMD_TRACEON: 2519022Ssam fprintf(fd, ", file=%*s\n", size, msg->rip_tracefile); 2529022Ssam break; 2539022Ssam 2549022Ssam case RIPCMD_TRACEOFF: 2559022Ssam fprintf(fd, "\n"); 2569022Ssam break; 2579022Ssam } 258*26960Skarels fflush(fd); 2599022Ssam } 260