/*-
* Copyright (c) 1997, 2005, 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
* NASA Ames Research Center.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* 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. 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.
*/
#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1983, 1988, 1993\
The Regents of the University of California. All rights reserved.");
#endif /* not lint */
/*
* 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 == 0) {
for (i = 0; i < TCP_NDEBUG; i++) {
struct tcp_debug *td = &tcp_debug[i];
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 == 0)
exit(0);
}
qsort(tcp_pcbs, npcbs, sizeof(caddr_t), numeric);
if (jflag) {
for (i = 0;;) {
printf("%lx", (long)tcp_pcbs[i]);
if (++i == npcbs)
break;
fputs(", ", stdout);
}
putchar('\n');
} else {
for (i = 0; i < npcbs; i++) {
printf("\n%lx:\n", (long)tcp_pcbs[i]);
dotrace(tcp_pcbs[i]);
}
}
exit(0);
}
static void
dotrace(caddr_t tcpcb)
{
struct tcp_debug *td;
int prev_debx = tcp_debx;
int i;
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);
switch (td->td_family) {
case AF_INET:
tcp_trace(td->td_act, td->td_ostate,
(struct tcpcb *)td->td_tcb, &td->td_cb,
td->td_family, &td->td_ti, td->td_req);
break;
#ifdef INET6
case AF_INET6:
tcp_trace(td->td_act, td->td_ostate,
(struct tcpcb *)td->td_tcb, &td->td_cb,
td->td_family, &td->td_ti6, td->td_req);
break;
#endif
default:
tcp_trace(td->td_act, td->td_ostate,
(struct tcpcb *)td->td_tcb, &td->td_cb,
td->td_family, NULL, td->td_req);
break;
}
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);
switch (td->td_family) {
case AF_INET:
tcp_trace(td->td_act, td->td_ostate,
(struct tcpcb *)td->td_tcb, &td->td_cb,
td->td_family, &td->td_ti, td->td_req);
break;
#ifdef INET6
case AF_INET6:
tcp_trace(td->td_act, td->td_ostate,
(struct tcpcb *)td->td_tcb, &td->td_cb,
td->td_family, &td->td_ti6, td->td_req);
break;
#endif
default:
tcp_trace(td->td_act, td->td_ostate,
(struct tcpcb *)td->td_tcb, &td->td_cb,
td->td_family, NULL, td->td_req);
break;
}
}
done:
if (follow) {
prev_debx = tcp_debx + 1;
if (prev_debx >= TCP_NDEBUG)
prev_debx = 0;
do {
sleep(1);
if (use_sysctl) {
size_t len = sizeof(tcp_debx);
if (sysctlbyname("net.inet.tcp.debx",
&tcp_debx, &len, NULL, 0) == -1)
err(1, "net.inet.tcp.debx");
} else
if (kvm_read(kd, nl[N_TCP_DEBX].n_value,
(char *)&tcp_debx, sizeof(tcp_debx)) !=
sizeof(tcp_debx))
errx(3, "tcp_debx: %s",
kvm_geterr(kd));
} while (tcp_debx == prev_debx);