* Copyright (c) 1983, 1988 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
"@(#) Copyright (c) 1983, 1988 Regents of the University of California.\n\
static char sccsid
[] = "@(#)trpt.c 5.6 (Berkeley) 9/22/88";
#include <sys/socketvar.h>
#include <netinet/in_pcb.h>
#include <netinet/in_systm.h>
#include <netinet/ip_var.h>
#include <netinet/tcp_fsm.h>
#include <netinet/tcp_seq.h>
#include <netinet/tcp_timer.h>
#include <netinet/tcp_var.h>
#include <netinet/tcpip.h>
#include <netinet/tcp_debug.h>
static struct pte
*Sysmap
;
static caddr_t tcp_pcbs
[TCP_NDEBUG
];
static int aflag
, kflag
, memf
, follow
, sflag
, tflag
;
int ch
, i
, jflag
, npcbs
, numeric();
char *system
, *core
, *malloc();
while ((ch
= getopt(argc
, argv
, "afjp:st")) != EOF
)
if (npcbs
>= TCP_NDEBUG
) {
fputs("trpt: too many pcb's specified\n",
(void)sscanf(optarg
, "%x", (int *)&tcp_pcbs
[npcbs
++]);
fputs("usage: trpt [-afjst] [-p hex-address] [system [core]]\n", stderr
);
if (nlist(system
, nl
) < 0 || !nl
[0].n_value
) {
fprintf(stderr
, "trpt: %s: no namelist\n", system
);
if ((memf
= open(core
, O_RDONLY
)) < 0) {
malloc((u_int
)(nl
[N_SYSSIZE
].n_value
* sizeof(struct pte
)));
fputs("arp: can't get memory for Sysmap.\n", stderr
);
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
)));
(void)klseek(memf
, (off_t
)nl
[N_TCP_DEBX
].n_value
, L_SET
);
if (read(memf
, (char *)&tcp_debx
, sizeof(tcp_debx
)) !=
perror("trpt: tcp_debx");
(void)klseek(memf
, (off_t
)nl
[N_TCP_DEBUG
].n_value
, L_SET
);
if (read(memf
, (char *)tcp_debug
, sizeof(tcp_debug
)) !=
perror("trpt: tcp_debug");
* 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
for (i
= 0; i
< TCP_NDEBUG
; i
++) {
register struct tcp_debug
*td
= &tcp_debug
[i
];
for (j
= 0; j
< npcbs
; j
++)
if (tcp_pcbs
[j
] == td
->td_tcb
)
tcp_pcbs
[npcbs
++] = td
->td_tcb
;
qsort(tcp_pcbs
, npcbs
, sizeof(caddr_t
), numeric
);
printf("%x", (int)tcp_pcbs
[i
]);
else for (i
= 0; i
< npcbs
; i
++) {
printf("\n%x:\n", (int)tcp_pcbs
[i
]);
register struct tcp_debug
*td
;
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
++) {
if (tcpcb
&& td
->td_tcb
!= tcpcb
)
ntime
= ntohl(td
->td_time
);
tcp_trace(td
->td_act
, td
->td_ostate
, td
->td_tcb
, &td
->td_cb
,
for (i
= 0; i
<= tcp_debx
% TCP_NDEBUG
; i
++) {
if (tcpcb
&& td
->td_tcb
!= tcpcb
)
ntime
= ntohl(td
->td_time
);
tcp_trace(td
->td_act
, td
->td_ostate
, td
->td_tcb
, &td
->td_cb
,
prev_debx
= tcp_debx
+ 1;
if (prev_debx
>= TCP_NDEBUG
)
(void)klseek(memf
, (off_t
)nl
[N_TCP_DEBX
].n_value
, L_SET
);
if (read(memf
, (char *)&tcp_debx
, sizeof(tcp_debx
)) !=
perror("trpt: tcp_debx");
} 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
)) !=
perror("trpt: tcp_debug");
tcp_trace(act
, ostate
, atp
, tp
, ti
, req
)
int flags
, len
, win
, timer
;
printf("%03ld %s:%s ",(ntime
/10) % 1000, tcpstates
[ostate
],
printf("(src=%s,%u, dst=%s,%u)", inet_ntoa(ti
->ti_src
),
ntohs(ti
->ti_sport
), inet_ntoa(ti
->ti_dst
),
len
-= sizeof(struct tcphdr
);
printf("[%lx..%lx)", seq
, seq
+ len
);
printf("%s%s", cp, "f"); \
printf("%s", prurequests
[req
]);
if (req
== PRU_SLOWTIMO
|| req
== PRU_FASTTIMO
)
printf("<%s>", tcptimers
[timer
]);
printf(" -> %s", tcpstates
[tp
->t_state
]);
/* print out internal state of tp !?! */
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
,
printf("\tsnd_wl1 %lx snd_wl2 %lx snd_wnd %x\n", tp
->snd_wl1
,
tp
->snd_wl2
, tp
->snd_wnd
);
register char *cp
= "\t";
for (i
= 0; i
< TCPT_NTIMERS
; i
++) {
printf("%s%s=%d", cp
, tcptimers
[i
], tp
->t_timer
[i
]);
printf(" (t_rxtshft=%d)", tp
->t_rxtshift
);
if (kflag
) { /* get kernel pte */
base
= ctob(Sysmap
[btop(base
)].pg_pfnum
) + (base
& PGOFSET
);
(void)lseek(fd
, base
, off
);