trace.c revision 15248
111820Sjulian/* 211820Sjulian * Copyright (c) 1985, 1993 311820Sjulian * The Regents of the University of California. All rights reserved. 411820Sjulian * 511820Sjulian * Copyright (c) 1995 John Hay. All rights reserved. 611820Sjulian * 711820Sjulian * This file includes significant work done at Cornell University by 811820Sjulian * Bill Nesheim. That work included by permission. 911820Sjulian * 1011820Sjulian * Redistribution and use in source and binary forms, with or without 1111820Sjulian * modification, are permitted provided that the following conditions 1211820Sjulian * are met: 1311820Sjulian * 1. Redistributions of source code must retain the above copyright 1411820Sjulian * notice, this list of conditions and the following disclaimer. 1511820Sjulian * 2. Redistributions in binary form must reproduce the above copyright 1611820Sjulian * notice, this list of conditions and the following disclaimer in the 1711820Sjulian * documentation and/or other materials provided with the distribution. 1811820Sjulian * 3. All advertising materials mentioning features or use of this software 1911820Sjulian * must display the following acknowledgement: 2011820Sjulian * This product includes software developed by the University of 2111820Sjulian * California, Berkeley and its contributors. 2211820Sjulian * 4. Neither the name of the University nor the names of its contributors 2311820Sjulian * may be used to endorse or promote products derived from this software 2411820Sjulian * without specific prior written permission. 2511820Sjulian * 2611820Sjulian * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2711820Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2811820Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2911820Sjulian * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3011820Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3111820Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3211820Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3311820Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3411820Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3511820Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3611820Sjulian * SUCH DAMAGE. 3711820Sjulian * 3815248Sjhay * $Id: trace.c,v 1.1 1995/10/26 21:28:29 julian Exp $ 3911820Sjulian */ 4011820Sjulian 4111820Sjulian#ifndef lint 4211820Sjulianstatic char sccsid[] = "@(#)trace.c 8.1 (Berkeley) 6/5/93"; 4311820Sjulian#endif /* not lint */ 4411820Sjulian 4511820Sjulian/* 4611820Sjulian * Routing Table Management Daemon 4711820Sjulian */ 4811820Sjulian#define RIPCMDS 4911820Sjulian#define SAPCMDS 5011820Sjulian#include <stdlib.h> 5111820Sjulian#include <unistd.h> 5211820Sjulian#include <sys/types.h> 5311820Sjulian#include <time.h> 5411820Sjulian#include "defs.h" 5511820Sjulian 5611820Sjulian#define NRECORDS 50 /* size of circular trace buffer */ 5711820Sjulian#ifdef DEBUG 5811820SjulianFILE *ftrace = stdout; 5911820Sjulianint tracing = 1; 6011820Sjulian#else DEBUG 6111820SjulianFILE *ftrace = NULL; 6211820Sjulianint tracing = 0; 6311820Sjulian#endif 6411820Sjulian 6511820Sjulianvoid dumpif(FILE *fd, struct interface *ifp); 6611820Sjulianvoid dumptrace(FILE *fd, char *dir, struct ifdebug *ifd); 6711820Sjulian 6811820Sjulianvoid 6911820Sjuliantraceinit(ifp) 7011820Sjulian register struct interface *ifp; 7111820Sjulian{ 7211820Sjulian static int iftraceinit(); 7311820Sjulian 7411820Sjulian if (iftraceinit(ifp, &ifp->int_input) && 7511820Sjulian iftraceinit(ifp, &ifp->int_output)) 7611820Sjulian return; 7711820Sjulian tracing = 0; 7811820Sjulian syslog(LOG_ERR, "traceinit: can't init %s\n", ifp->int_name); 7911820Sjulian} 8011820Sjulian 8111820Sjulianstatic int 8211820Sjulianiftraceinit(ifp, ifd) 8311820Sjulian struct interface *ifp; 8411820Sjulian register struct ifdebug *ifd; 8511820Sjulian{ 8611820Sjulian register struct iftrace *t; 8711820Sjulian 8811820Sjulian ifd->ifd_records = 8911820Sjulian (struct iftrace *)malloc(NRECORDS * sizeof (struct iftrace)); 9011820Sjulian if (ifd->ifd_records == 0) 9111820Sjulian return (0); 9211820Sjulian ifd->ifd_front = ifd->ifd_records; 9311820Sjulian ifd->ifd_count = 0; 9411820Sjulian for (t = ifd->ifd_records; t < ifd->ifd_records + NRECORDS; t++) { 9511820Sjulian t->ift_size = 0; 9611820Sjulian t->ift_packet = 0; 9711820Sjulian } 9811820Sjulian ifd->ifd_if = ifp; 9911820Sjulian return (1); 10011820Sjulian} 10111820Sjulian 10211820Sjulianvoid 10311820Sjuliantraceon(file) 10411820Sjulian char *file; 10511820Sjulian{ 10611820Sjulian 10711820Sjulian if (ftrace != NULL) 10811820Sjulian return; 10911820Sjulian ftrace = fopen(file, "a"); 11011820Sjulian if (ftrace == NULL) 11111820Sjulian return; 11211820Sjulian dup2(fileno(ftrace), 1); 11311820Sjulian dup2(fileno(ftrace), 2); 11411820Sjulian tracing = 1; 11511820Sjulian} 11611820Sjulian 11711820Sjulianvoid 11811820Sjuliantraceoff(void) 11911820Sjulian{ 12011820Sjulian if (!tracing) 12111820Sjulian return; 12211820Sjulian if (ftrace != NULL) 12311820Sjulian fclose(ftrace); 12411820Sjulian ftrace = NULL; 12511820Sjulian tracing = 0; 12611820Sjulian} 12711820Sjulian 12811820Sjulianvoid 12911820Sjuliantrace(ifd, who, p, len, m) 13011820Sjulian register struct ifdebug *ifd; 13111820Sjulian struct sockaddr *who; 13211820Sjulian char *p; 13311820Sjulian int len, m; 13411820Sjulian{ 13511820Sjulian register struct iftrace *t; 13611820Sjulian 13711820Sjulian if (ifd->ifd_records == 0) 13811820Sjulian return; 13911820Sjulian t = ifd->ifd_front++; 14011820Sjulian if (ifd->ifd_front >= ifd->ifd_records + NRECORDS) 14111820Sjulian ifd->ifd_front = ifd->ifd_records; 14211820Sjulian if (ifd->ifd_count < NRECORDS) 14311820Sjulian ifd->ifd_count++; 14411820Sjulian if (t->ift_size > 0 && t->ift_packet) 14511820Sjulian free(t->ift_packet); 14611820Sjulian t->ift_packet = 0; 14711820Sjulian t->ift_stamp = time(0); 14811820Sjulian t->ift_who = *who; 14911820Sjulian if (len > 0) { 15011820Sjulian t->ift_packet = malloc(len); 15111820Sjulian if (t->ift_packet) 15211820Sjulian bcopy(p, t->ift_packet, len); 15311820Sjulian else 15411820Sjulian len = 0; 15511820Sjulian } 15611820Sjulian t->ift_size = len; 15711820Sjulian t->ift_metric = m; 15811820Sjulian} 15911820Sjulian 16011820Sjulianvoid 16111820Sjuliantraceaction(fd, action, rt) 16211820Sjulian FILE *fd; 16311820Sjulian char *action; 16411820Sjulian struct rt_entry *rt; 16511820Sjulian{ 16611820Sjulian struct sockaddr_ipx *dst, *gate; 16711820Sjulian static struct bits { 16811820Sjulian int t_bits; 16911820Sjulian char *t_name; 17011820Sjulian } flagbits[] = { 17111820Sjulian { RTF_UP, "UP" }, 17211820Sjulian { RTF_GATEWAY, "GATEWAY" }, 17311820Sjulian { RTF_HOST, "HOST" }, 17411820Sjulian { 0 } 17511820Sjulian }, statebits[] = { 17611820Sjulian { RTS_PASSIVE, "PASSIVE" }, 17711820Sjulian { RTS_REMOTE, "REMOTE" }, 17811820Sjulian { RTS_INTERFACE,"INTERFACE" }, 17911820Sjulian { RTS_CHANGED, "CHANGED" }, 18011820Sjulian { 0 } 18111820Sjulian }; 18211820Sjulian register struct bits *p; 18311820Sjulian register int first; 18411820Sjulian char *cp; 18511820Sjulian 18611820Sjulian if (fd == NULL) 18711820Sjulian return; 18811820Sjulian fprintf(fd, "%s ", action); 18911820Sjulian dst = (struct sockaddr_ipx *)&rt->rt_dst; 19011820Sjulian gate = (struct sockaddr_ipx *)&rt->rt_router; 19111820Sjulian fprintf(fd, "dst %s, ", ipxdp_ntoa(&dst->sipx_addr)); 19211820Sjulian fprintf(fd, "router %s, metric %d, ticks %d, flags", 19311820Sjulian ipxdp_ntoa(&gate->sipx_addr), rt->rt_metric, rt->rt_ticks); 19411820Sjulian cp = " %s"; 19511820Sjulian for (first = 1, p = flagbits; p->t_bits > 0; p++) { 19611820Sjulian if ((rt->rt_flags & p->t_bits) == 0) 19711820Sjulian continue; 19811820Sjulian fprintf(fd, cp, p->t_name); 19911820Sjulian if (first) { 20011820Sjulian cp = "|%s"; 20111820Sjulian first = 0; 20211820Sjulian } 20311820Sjulian } 20411820Sjulian fprintf(fd, " state"); 20511820Sjulian cp = " %s"; 20611820Sjulian for (first = 1, p = statebits; p->t_bits > 0; p++) { 20711820Sjulian if ((rt->rt_state & p->t_bits) == 0) 20811820Sjulian continue; 20911820Sjulian fprintf(fd, cp, p->t_name); 21011820Sjulian if (first) { 21111820Sjulian cp = "|%s"; 21211820Sjulian first = 0; 21311820Sjulian } 21411820Sjulian } 21511820Sjulian putc('\n', fd); 21611820Sjulian if (!tracepackets && (rt->rt_state & RTS_PASSIVE) == 0 && rt->rt_ifp) 21711820Sjulian dumpif(fd, rt->rt_ifp); 21811820Sjulian fflush(fd); 21911820Sjulian} 22011820Sjulian 22111820Sjulianvoid 22211820Sjuliandumpif(fd, ifp) 22311820Sjulian register struct interface *ifp; 22411820Sjulian FILE *fd; 22511820Sjulian{ 22611820Sjulian if (ifp->int_input.ifd_count || ifp->int_output.ifd_count) { 22711820Sjulian fprintf(fd, "*** Packet history for interface %s ***\n", 22811820Sjulian ifp->int_name); 22911820Sjulian dumptrace(fd, "to", &ifp->int_output); 23011820Sjulian dumptrace(fd, "from", &ifp->int_input); 23111820Sjulian fprintf(fd, "*** end packet history ***\n"); 23211820Sjulian } 23311820Sjulian} 23411820Sjulian 23511820Sjulianvoid 23611820Sjuliandumptrace(fd, dir, ifd) 23711820Sjulian FILE *fd; 23811820Sjulian char *dir; 23911820Sjulian register struct ifdebug *ifd; 24011820Sjulian{ 24111820Sjulian register struct iftrace *t; 24211820Sjulian char *cp = !strcmp(dir, "to") ? "Output" : "Input"; 24311820Sjulian 24411820Sjulian if (ifd->ifd_front == ifd->ifd_records && 24511820Sjulian ifd->ifd_front->ift_size == 0) { 24611820Sjulian fprintf(fd, "%s: no packets.\n", cp); 24711820Sjulian return; 24811820Sjulian } 24911820Sjulian fprintf(fd, "%s trace:\n", cp); 25011820Sjulian t = ifd->ifd_front - ifd->ifd_count; 25111820Sjulian if (t < ifd->ifd_records) 25211820Sjulian t += NRECORDS; 25311820Sjulian for ( ; ifd->ifd_count; ifd->ifd_count--, t++) { 25411820Sjulian if (t >= ifd->ifd_records + NRECORDS) 25511820Sjulian t = ifd->ifd_records; 25611820Sjulian if (t->ift_size == 0) 25711820Sjulian continue; 25811820Sjulian fprintf(fd, "%.24s: metric=%d\n", ctime(&t->ift_stamp), 25911820Sjulian t->ift_metric); 26011820Sjulian dumppacket(fd, dir, &t->ift_who, t->ift_packet, t->ift_size); 26111820Sjulian } 26211820Sjulian} 26311820Sjulian 26411820Sjulianvoid 26511820Sjuliandumppacket(fd, dir, source, cp, size) 26611820Sjulian FILE *fd; 26711820Sjulian char *dir; 26811820Sjulian struct sockaddr *source; 26911820Sjulian char *cp; 27011820Sjulian register int size; 27111820Sjulian{ 27211820Sjulian register struct rip *msg = (struct rip *)cp; 27311820Sjulian register struct netinfo *n; 27411820Sjulian struct sockaddr_ipx *who = (struct sockaddr_ipx *)source; 27511820Sjulian 27611820Sjulian if (msg->rip_cmd && ntohs(msg->rip_cmd) < RIPCMD_MAX) 27711820Sjulian fprintf(fd, "%s %s %s#%x", ripcmds[ntohs(msg->rip_cmd)], 27811820Sjulian dir, ipxdp_ntoa(&who->sipx_addr), 27911820Sjulian ntohs(who->sipx_addr.x_port)); 28011820Sjulian else { 28111820Sjulian fprintf(fd, "Bad cmd 0x%x %s %s#%x\n", ntohs(msg->rip_cmd), 28211820Sjulian dir, ipxdp_ntoa(&who->sipx_addr), 28311820Sjulian ntohs(who->sipx_addr.x_port)); 28411820Sjulian fprintf(fd, "size=%d cp=%x packet=%x\n", size, 28511820Sjulian (u_int)cp, (u_int)packet); 28611820Sjulian return; 28711820Sjulian } 28811820Sjulian switch (ntohs(msg->rip_cmd)) { 28911820Sjulian 29011820Sjulian case RIPCMD_REQUEST: 29111820Sjulian case RIPCMD_RESPONSE: 29211820Sjulian fprintf(fd, ":\n"); 29311820Sjulian size -= sizeof (u_short); 29411820Sjulian n = msg->rip_nets; 29511820Sjulian for (; size > 0; n++, size -= sizeof (struct netinfo)) { 29611820Sjulian if (size < sizeof (struct netinfo)) 29711820Sjulian break; 29811820Sjulian fprintf(fd, "\tnet %s metric %d ticks %d\n", 29911820Sjulian ipxdp_nettoa(n->rip_dst), 30011820Sjulian ntohs(n->rip_metric), 30111820Sjulian ntohs(n->rip_ticks)); 30211820Sjulian } 30311820Sjulian break; 30411820Sjulian 30511820Sjulian } 30611820Sjulian} 30711820Sjulian 30811820Sjulianvoid 30911820Sjuliandumpsappacket(fd, dir, source, cp, size) 31011820Sjulian FILE *fd; 31111820Sjulian char *dir; 31211820Sjulian struct sockaddr *source; 31311820Sjulian char *cp; 31411820Sjulian register int size; 31511820Sjulian{ 31611820Sjulian register struct sap_packet *msg = (struct sap_packet *)cp; 31711820Sjulian register struct sap_info *n; 31811820Sjulian struct sockaddr_ipx *who = (struct sockaddr_ipx *)source; 31911820Sjulian 32011820Sjulian if (msg->sap_cmd && ntohs(msg->sap_cmd) < SAPCMD_MAX) 32111820Sjulian fprintf(fd, "%s %s %s#%x", sapcmds[ntohs(msg->sap_cmd)], 32211820Sjulian dir, ipxdp_ntoa(&who->sipx_addr), 32311820Sjulian ntohs(who->sipx_addr.x_port)); 32411820Sjulian else { 32511820Sjulian fprintf(fd, "Bad cmd 0x%x %s %s#%x\n", ntohs(msg->sap_cmd), 32611820Sjulian dir, ipxdp_ntoa(&who->sipx_addr), 32711820Sjulian ntohs(who->sipx_addr.x_port)); 32811820Sjulian fprintf(fd, "size=%d cp=%x packet=%x\n", size, 32911820Sjulian (u_int)cp, (u_int)packet); 33011820Sjulian return; 33111820Sjulian } 33211820Sjulian switch (ntohs(msg->sap_cmd)) { 33311820Sjulian 33411820Sjulian case SAP_REQ: 33511820Sjulian case SAP_RESP: 33611820Sjulian case SAP_REQ_NEAR: 33711820Sjulian case SAP_RESP_NEAR: 33811820Sjulian fprintf(fd, ":\n"); 33911820Sjulian size -= sizeof (u_short); 34011820Sjulian n = msg->sap; 34111820Sjulian for (; size > 0; n++, size -= sizeof (struct sap_info)) { 34211820Sjulian if (size < sizeof (struct sap_info)) 34311820Sjulian break; 34411820Sjulian fprintf(fd, " service %04X %-20.20s " 34511820Sjulian "addr %s.%04X metric %d\n", 34611820Sjulian ntohs(n->ServType), 34711820Sjulian n->ServName, 34811820Sjulian ipxdp_ntoa(&n->ipx), 34911820Sjulian ntohs(n->ipx.x_port), 35011820Sjulian ntohs(n->hops)); 35111820Sjulian } 35211820Sjulian break; 35311820Sjulian 35411820Sjulian } 35511820Sjulian} 35611820Sjulian 35711820Sjulianvoid 35811820Sjuliandumpsaptable(fd, sh) 35911820Sjulian FILE *fd; 36011820Sjulian struct sap_hash *sh; 36111820Sjulian{ 36211820Sjulian register struct sap_entry *sap; 36311820Sjulian struct sap_hash *hash; 36411820Sjulian int x = 0; 36511820Sjulian 36611820Sjulian fprintf(fd, "------- SAP table dump. -------\n"); 36711820Sjulian for (hash = sh; hash < &sh[SAPHASHSIZ]; hash++, x++) { 36811820Sjulian fprintf(fd, "HASH %d\n", x); 36911820Sjulian sap = hash->forw; 37011820Sjulian for (; sap != (struct sap_entry *)hash; sap = sap->forw) { 37111820Sjulian fprintf(fd, " service %04X %-20.20s " 37211820Sjulian "addr %s.%04X %c metric %d\n", 37311820Sjulian ntohs(sap->sap.ServType), 37411820Sjulian sap->sap.ServName, 37511820Sjulian ipxdp_ntoa(&sap->sap.ipx), 37611820Sjulian ntohs(sap->sap.ipx.x_port), 37711820Sjulian (sap->clone ? 'C' : ' '), 37811820Sjulian ntohs(sap->sap.hops)); 37911820Sjulian } 38011820Sjulian } 38111820Sjulian fprintf(fd, "\n"); 38211820Sjulian} 38311820Sjulian 38415248Sjhayvoid 38515248Sjhaydumpriptable(fd) 38615248Sjhay FILE *fd; 38715248Sjhay{ 38815248Sjhay register struct rt_entry *rip; 38915248Sjhay struct rthash *hash; 39015248Sjhay int x; 39115248Sjhay struct rthash *rh = nethash; 39215248Sjhay 39315248Sjhay fprintf(fd, "------- RIP table dump. -------\n"); 39415248Sjhay x = 0; 39515248Sjhay fprintf(fd, "Network table.\n"); 39615248Sjhay 39715248Sjhay for (hash = rh; hash < &rh[ROUTEHASHSIZ]; hash++, x++) { 39815248Sjhay fprintf(fd, "HASH %d\n", x); 39915248Sjhay rip = hash->rt_forw; 40015248Sjhay for (; rip != (struct rt_entry *)hash; rip = rip->rt_forw) { 40115248Sjhay fprintf(fd, " dest %s\t", 40215248Sjhay ipxdp_ntoa(&satoipx_addr(rip->rt_dst))); 40315248Sjhay fprintf(fd, "%s metric %d, ticks %d\n", 40415248Sjhay ipxdp_ntoa(&satoipx_addr(rip->rt_router)), 40515248Sjhay rip->rt_metric, 40615248Sjhay rip->rt_ticks); 40715248Sjhay } 40815248Sjhay } 40915248Sjhay fprintf(fd, "\n"); 41015248Sjhay} 41115248Sjhay 41211820Sjulianunion ipx_net_u net; 41311820Sjulian 41411820Sjulianchar * 41511820Sjulianipxdp_nettoa(val) 41611820Sjulianunion ipx_net val; 41711820Sjulian{ 41811820Sjulian static char buf[100]; 41911820Sjulian net.net_e = val; 42011820Sjulian (void)sprintf(buf, "%lx", ntohl(net.long_e)); 42111820Sjulian return (buf); 42211820Sjulian} 42311820Sjulian 42411820Sjulian 42511820Sjulianchar * 42611820Sjulianipxdp_ntoa(addr) 42711820Sjulianstruct ipx_addr *addr; 42811820Sjulian{ 42911820Sjulian static char buf[100]; 43011820Sjulian 43111820Sjulian (void)sprintf(buf, "%s#%x:%x:%x:%x:%x:%x", 43211820Sjulian ipxdp_nettoa(addr->x_net), 43311820Sjulian addr->x_host.c_host[0], addr->x_host.c_host[1], 43411820Sjulian addr->x_host.c_host[2], addr->x_host.c_host[3], 43511820Sjulian addr->x_host.c_host[4], addr->x_host.c_host[5]); 43611820Sjulian 43711820Sjulian return(buf); 43811820Sjulian} 439