diff options
author | rgrimes <rgrimes@FreeBSD.org> | 1994-05-26 05:23:31 +0000 |
---|---|---|
committer | rgrimes <rgrimes@FreeBSD.org> | 1994-05-26 05:23:31 +0000 |
commit | 862fdf11a2ede45dec0da01ed575525d79468981 (patch) | |
tree | 7a1c88ccb8006476bd4b4a548a6ad48fbfc33a01 /usr.sbin/trpt | |
parent | 8e1a19ddde0df113b0b26b0ea621afd61dbaf91f (diff) | |
download | FreeBSD-src-862fdf11a2ede45dec0da01ed575525d79468981.zip FreeBSD-src-862fdf11a2ede45dec0da01ed575525d79468981.tar.gz |
BSD 4.4 Lite usr.sbin Sources
Diffstat (limited to 'usr.sbin/trpt')
-rw-r--r-- | usr.sbin/trpt/Makefile | 8 | ||||
-rw-r--r-- | usr.sbin/trpt/trpt.8 | 151 | ||||
-rw-r--r-- | usr.sbin/trpt/trpt.c | 414 |
3 files changed, 573 insertions, 0 deletions
diff --git a/usr.sbin/trpt/Makefile b/usr.sbin/trpt/Makefile new file mode 100644 index 0000000..9057f65 --- /dev/null +++ b/usr.sbin/trpt/Makefile @@ -0,0 +1,8 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= trpt +MAN8= trpt.0 +BINGRP= kmem +BINMODE=2555 + +.include <bsd.prog.mk> diff --git a/usr.sbin/trpt/trpt.8 b/usr.sbin/trpt/trpt.8 new file mode 100644 index 0000000..8cc6c2a --- /dev/null +++ b/usr.sbin/trpt/trpt.8 @@ -0,0 +1,151 @@ +.\" Copyright (c) 1983, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)trpt.8 8.2 (Berkeley) 12/11/93 +.\" +.Dd December 11, 1993 +.Dt TRPT 8 +.Os BSD 4.2 +.Sh NAME +.Nm trpt +.Nd transliterate protocol trace +.Sh SYNOPSIS +.Nm trpt +.Op Fl a +.Op Fl f +.Op Fl j +.Op Fl p Ar hex-address +.Op Fl s +.Op Fl t +.Oo +.Ar system Op Ar core +.Oc +.Sh DESCRIPTION +.Nm Trpt +interrogates the buffer of +.Tn TCP +trace records created +when a socket is marked for +.Dq debugging +(see +.Xr setsockopt 2 ) , +and prints a readable description of these records. +When no options are supplied, +.Nm trpt +prints all the trace records found in the system +grouped according to +.Tn TCP +connection protocol control +block +.Pq Tn PCB . +The following options may be used to +alter this behavior. +.Bl -tag -width Ds +.It Fl a +In addition to the normal output, +print the values of the source and destination +addresses for each packet recorded. +.It Fl f +Follow the trace as it occurs, waiting a short time for additional records +each time the end of the log is reached. +.It Fl j +Just give a list of the protocol control block +addresses for which there are trace records. +.It Fl p +Show only trace records associated with the protocol +control block at the given address +.Ar hex-address . +.It Fl s +In addition to the normal output, +print a detailed description of the packet +sequencing information. +.It Fl t +in addition to the normal output, +print the values for all timers at each +point in the trace. +.El +.Pp +The recommended use of +.Nm trpt +is as follows. +Isolate the problem and enable debugging on the +socket(s) involved in the connection. +Find the address of the protocol control blocks +associated with the sockets using the +.Fl A +option to +.Xr netstat 1 . +Then run +.Nm trpt +with the +.Fl p +option, supplying the associated +protocol control block addresses. +The +.Fl f +option can be used to follow the trace log once the trace is located. +If there are +many sockets using the debugging option, the +.Fl j +option may be useful in checking to see if +any trace records are present for the socket in +question. +.Pp +If debugging is being performed on a system or +core file other than the default, the last two +arguments may be used to supplant the defaults. +.Sh FILES +.Bl -tag -width /dev/kmem -compact +.It Pa /vmunix +.It Pa /dev/kmem +.El +.Sh SEE ALSO +.Xr netstat 1 , +.Xr setsockopt 2 , +.Xr trsp 8 +.Sh DIAGNOSTICS +.Bl -tag -width Ds +.It Sy no namelist +When the system image doesn't +contain the proper symbols to find the trace buffer; +others which should be self explanatory. +.El +.Sh BUGS +Should also print the data for each input or output, +but this is not saved in the race record. +.Pp +The output format is inscrutable and should be described +here. +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.2 . diff --git a/usr.sbin/trpt/trpt.c b/usr.sbin/trpt/trpt.c new file mode 100644 index 0000000..7452cdd --- /dev/null +++ b/usr.sbin/trpt/trpt.c @@ -0,0 +1,414 @@ +/* + * Copyright (c) 1983, 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1983, 1988, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)trpt.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include <sys/param.h> +#if BSD >= 199103 +#define NEWVM +#endif +#ifndef NEWVM +#include <machine/pte.h> +#include <sys/vmmac.h> +#endif +#include <sys/socket.h> +#include <sys/socketvar.h> +#define PRUREQUESTS +#include <sys/protosw.h> +#include <sys/file.h> + +#include <net/route.h> +#include <net/if.h> + +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/ip.h> +#include <netinet/in_pcb.h> +#include <netinet/ip_var.h> +#include <netinet/tcp.h> +#define TCPSTATES +#include <netinet/tcp_fsm.h> +#include <netinet/tcp_seq.h> +#define TCPTIMERS +#include <netinet/tcp_timer.h> +#include <netinet/tcp_var.h> +#include <netinet/tcpip.h> +#define TANAMES +#include <netinet/tcp_debug.h> + +#include <arpa/inet.h> + +#include <stdio.h> +#include <errno.h> +#include <nlist.h> +#include <paths.h> + +struct nlist nl[] = { +#define N_TCP_DEBUG 0 + { "_tcp_debug" }, +#define N_TCP_DEBX 1 + { "_tcp_debx" }, +#ifndef NEWVM +#define N_SYSMAP 2 + { "_Sysmap" }, +#define N_SYSSIZE 3 + { "_Syssize" }, +#endif + { "" }, +}; + +#ifndef NEWVM +static struct pte *Sysmap; +#endif +static caddr_t tcp_pcbs[TCP_NDEBUG]; +static n_time ntime; +static int aflag, kflag, memf, follow, sflag, tflag; + +main(argc, argv) + int argc; + char **argv; +{ + extern char *optarg; + extern int optind; + int ch, i, jflag, npcbs, numeric(); + char *system, *core, *malloc(); + off_t lseek(); + + jflag = npcbs = 0; + while ((ch = getopt(argc, argv, "afjp:st")) != EOF) + switch (ch) { + case 'a': + ++aflag; + break; + case 'f': + ++follow; + setlinebuf(stdout); + break; + case 'j': + ++jflag; + break; + case 'p': + if (npcbs >= TCP_NDEBUG) { + fputs("trpt: too many pcb's specified\n", + stderr); + exit(1); + } + (void)sscanf(optarg, "%x", (int *)&tcp_pcbs[npcbs++]); + break; + case 's': + ++sflag; + break; + case 't': + ++tflag; + break; + case '?': + default: + (void)fprintf(stderr, +"usage: trpt [-afjst] [-p hex-address] [system [core]]\n"); + exit(1); + } + argc -= optind; + argv += optind; + + core = _PATH_KMEM; + if (argc > 0) { + system = *argv; + argc--, argv++; + if (argc > 0) { + core = *argv; + argc--, argv++; + ++kflag; + } + /* + * Discard setgid privileges if not the running kernel so that + * bad guys can't print interesting stuff from kernel memory. + */ + setgid(getgid()); + } + else + system = _PATH_UNIX; + + if (nlist(system, nl) < 0 || !nl[0].n_value) { + fprintf(stderr, "trpt: %s: no namelist\n", system); + exit(1); + } + if ((memf = open(core, O_RDONLY)) < 0) { + perror(core); + exit(2); + } + if (kflag) { +#ifdef NEWVM + fputs("trpt: can't do core files yet\n", stderr); + exit(1); +#else + off_t off; + + Sysmap = (struct pte *) + malloc((u_int)(nl[N_SYSSIZE].n_value * sizeof(struct pte))); + if (!Sysmap) { + fputs("trpt: can't get memory for Sysmap.\n", stderr); + exit(1); + } + off = nl[N_SYSMAP].n_value & ~KERNBASE; + (void)lseek(memf, off, L_SET); + (void)read(memf, (char *)Sysmap, + (int)(nl[N_SYSSIZE].n_value * sizeof(struct pte))); +#endif + } + (void)klseek(memf, (off_t)nl[N_TCP_DEBX].n_value, L_SET); + if (read(memf, (char *)&tcp_debx, sizeof(tcp_debx)) != + sizeof(tcp_debx)) { + perror("trpt: tcp_debx"); + exit(3); + } + (void)klseek(memf, (off_t)nl[N_TCP_DEBUG].n_value, L_SET); + if (read(memf, (char *)tcp_debug, sizeof(tcp_debug)) != + sizeof(tcp_debug)) { + perror("trpt: tcp_debug"); + exit(3); + } + /* + * If no control blocks have been specified, figure + * out how many distinct one we have and summarize + * them in tcp_pcbs for sorting the trace records + * below. + */ + if (!npcbs) { + for (i = 0; i < TCP_NDEBUG; i++) { + register struct tcp_debug *td = &tcp_debug[i]; + register int j; + + if (td->td_tcb == 0) + continue; + for (j = 0; j < npcbs; j++) + if (tcp_pcbs[j] == td->td_tcb) + break; + if (j >= npcbs) + tcp_pcbs[npcbs++] = td->td_tcb; + } + if (!npcbs) + exit(0); + } + qsort(tcp_pcbs, npcbs, sizeof(caddr_t), numeric); + if (jflag) { + for (i = 0;;) { + printf("%x", (int)tcp_pcbs[i]); + if (++i == npcbs) + break; + fputs(", ", stdout); + } + putchar('\n'); + } + else for (i = 0; i < npcbs; i++) { + printf("\n%x:\n", (int)tcp_pcbs[i]); + dotrace(tcp_pcbs[i]); + } + exit(0); +} + +dotrace(tcpcb) + register caddr_t tcpcb; +{ + register struct tcp_debug *td; + register int i; + int prev_debx = tcp_debx; + +again: if (--tcp_debx < 0) + tcp_debx = TCP_NDEBUG - 1; + for (i = prev_debx % TCP_NDEBUG; i < TCP_NDEBUG; i++) { + td = &tcp_debug[i]; + if (tcpcb && td->td_tcb != tcpcb) + continue; + ntime = ntohl(td->td_time); + tcp_trace(td->td_act, td->td_ostate, td->td_tcb, &td->td_cb, + &td->td_ti, td->td_req); + if (i == tcp_debx) + goto done; + } + for (i = 0; i <= tcp_debx % TCP_NDEBUG; i++) { + td = &tcp_debug[i]; + if (tcpcb && td->td_tcb != tcpcb) + continue; + ntime = ntohl(td->td_time); + tcp_trace(td->td_act, td->td_ostate, td->td_tcb, &td->td_cb, + &td->td_ti, td->td_req); + } +done: if (follow) { + prev_debx = tcp_debx + 1; + if (prev_debx >= TCP_NDEBUG) + prev_debx = 0; + do { + sleep(1); + (void)klseek(memf, (off_t)nl[N_TCP_DEBX].n_value, L_SET); + if (read(memf, (char *)&tcp_debx, sizeof(tcp_debx)) != + sizeof(tcp_debx)) { + perror("trpt: tcp_debx"); + exit(3); + } + } while (tcp_debx == prev_debx); + (void)klseek(memf, (off_t)nl[N_TCP_DEBUG].n_value, L_SET); + if (read(memf, (char *)tcp_debug, sizeof(tcp_debug)) != + sizeof(tcp_debug)) { + perror("trpt: tcp_debug"); + exit(3); + } + goto again; + } +} + +/* + * Tcp debug routines + */ +/*ARGSUSED*/ +tcp_trace(act, ostate, atp, tp, ti, req) + short act, ostate; + struct tcpcb *atp, *tp; + struct tcpiphdr *ti; + int req; +{ + tcp_seq seq, ack; + int flags, len, win, timer; + + printf("%03ld %s:%s ",(ntime/10) % 1000, tcpstates[ostate], + tanames[act]); + switch (act) { + case TA_INPUT: + case TA_OUTPUT: + case TA_DROP: + if (aflag) { + printf("(src=%s,%u, ", + inet_ntoa(ti->ti_src), ntohs(ti->ti_sport)); + printf("dst=%s,%u)", + inet_ntoa(ti->ti_dst), ntohs(ti->ti_dport)); + } + seq = ti->ti_seq; + ack = ti->ti_ack; + len = ti->ti_len; + win = ti->ti_win; + if (act == TA_OUTPUT) { + seq = ntohl(seq); + ack = ntohl(ack); + len = ntohs(len); + win = ntohs(win); + } + if (act == TA_OUTPUT) + len -= sizeof(struct tcphdr); + if (len) + printf("[%lx..%lx)", seq, seq + len); + else + printf("%lx", seq); + printf("@%lx", ack); + if (win) + printf("(win=%x)", win); + flags = ti->ti_flags; + if (flags) { + register char *cp = "<"; +#define pf(flag, string) { \ + if (ti->ti_flags&flag) { \ + (void)printf("%s%s", cp, string); \ + cp = ","; \ + } \ +} + pf(TH_SYN, "SYN"); + pf(TH_ACK, "ACK"); + pf(TH_FIN, "FIN"); + pf(TH_RST, "RST"); + pf(TH_PUSH, "PUSH"); + pf(TH_URG, "URG"); + printf(">"); + } + break; + case TA_USER: + timer = req >> 8; + req &= 0xff; + printf("%s", prurequests[req]); + if (req == PRU_SLOWTIMO || req == PRU_FASTTIMO) + printf("<%s>", tcptimers[timer]); + break; + } + printf(" -> %s", tcpstates[tp->t_state]); + /* print out internal state of tp !?! */ + printf("\n"); + if (sflag) { + printf("\trcv_nxt %lx rcv_wnd %x snd_una %lx snd_nxt %lx snd_max %lx\n", + tp->rcv_nxt, tp->rcv_wnd, tp->snd_una, tp->snd_nxt, + tp->snd_max); + printf("\tsnd_wl1 %lx snd_wl2 %lx snd_wnd %x\n", tp->snd_wl1, + tp->snd_wl2, tp->snd_wnd); + } + /* print out timers? */ + if (tflag) { + register char *cp = "\t"; + register int i; + + for (i = 0; i < TCPT_NTIMERS; i++) { + if (tp->t_timer[i] == 0) + continue; + printf("%s%s=%d", cp, tcptimers[i], tp->t_timer[i]); + if (i == TCPT_REXMT) + printf(" (t_rxtshft=%d)", tp->t_rxtshift); + cp = ", "; + } + if (*cp != '\t') + putchar('\n'); + } +} + +numeric(c1, c2) + caddr_t *c1, *c2; +{ + return(*c1 - *c2); +} + +klseek(fd, base, off) + int fd, off; + off_t base; +{ + off_t lseek(); + +#ifndef NEWVM + if (kflag) { /* get kernel pte */ + base &= ~KERNBASE; + base = ctob(Sysmap[btop(base)].pg_pfnum) + (base & PGOFSET); + } +#endif + (void)lseek(fd, base, off); +} |