aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Tuexen <tuexen@FreeBSD.org>2023-04-20 22:09:40 +0000
committerMichael Tuexen <tuexen@FreeBSD.org>2023-04-20 22:09:40 +0000
commitd7339c42673a84e222f630e80b5606776b755229 (patch)
treef673125cfd96be33598025a5f879686325c7a3e8
parent312c06634ec3b405377840573f932fd937f51a61 (diff)
downloadsrc-d7339c42673a84e222f630e80b5606776b755229.tar.gz
src-d7339c42673a84e222f630e80b5606776b755229.zip
trpt: fix several bugs and add deprecation notice
This patch fixes several bugs releated to trpt including * the computation of the TCP payload bytes, in particular when TCP options are present or IPv4 is used. * the logging of incoming and outgoing packets. * the logging of timers, in particular add support for logging of the delayed ack timer. Also add a deprecation note, since support for this utility has been removed from the main branch. Therefore, this is a direct commit to stable/13. Reviewed by: cc, glebius, rrs Sponsored by: Netflix, Inc. Differential Revision: https://reviews.freebsd.org/D39436
-rw-r--r--sys/netinet/tcp_debug.c9
-rw-r--r--sys/netinet/tcp_input.c13
-rw-r--r--sys/netinet/tcp_output.c28
-rw-r--r--sys/netinet/tcp_timer.c20
-rw-r--r--sys/netinet/tcp_timer.h6
-rw-r--r--usr.sbin/trpt/trpt.831
-rw-r--r--usr.sbin/trpt/trpt.c10
7 files changed, 72 insertions, 45 deletions
diff --git a/sys/netinet/tcp_debug.c b/sys/netinet/tcp_debug.c
index aedaa131095f..640940b1ce8c 100644
--- a/sys/netinet/tcp_debug.c
+++ b/sys/netinet/tcp_debug.c
@@ -177,13 +177,13 @@ tcp_trace(short act, short ostate, struct tcpcb *tp, void *ipgen,
#ifdef INET6
isipv6 ? ntohs(((struct ip6_hdr *)ipgen)->ip6_plen) :
#endif
- ntohs(((struct ip *)ipgen)->ip_len);
+ ntohs(((struct ip *)ipgen)->ip_len) -
+ (((struct ip *)ipgen)->ip_hl << 2);
if (act == TA_OUTPUT) {
seq = ntohl(seq);
ack = ntohl(ack);
}
- if (act == TA_OUTPUT)
- len -= sizeof (struct tcphdr);
+ len -= th->th_off << 2;
if (len)
printf("[%x..%x)", seq, seq+len);
else
@@ -205,7 +205,8 @@ tcp_trace(short act, short ostate, struct tcpcb *tp, void *ipgen,
case TA_USER:
printf("%s", prurequests[req&0xff]);
- if ((req & 0xff) == PRU_SLOWTIMO)
+ if ((req & 0xff) == PRU_SLOWTIMO ||
+ (req & 0xff) == PRU_FASTTIMO)
printf("<%s>", tcptimers[req>>8]);
break;
}
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 9bc9923530e0..bb2a0e497dcf 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -1561,7 +1561,18 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
*/
u_char tcp_saveipgen[IP6_HDR_LEN];
struct tcphdr tcp_savetcp;
- short ostate = 0;
+ short ostate;
+
+ if (so->so_options & SO_DEBUG) {
+ ostate = tp->t_state;
+#ifdef INET6
+ if (mtod(m, struct ip *)->ip_v == 6)
+ bcopy(mtod(m, char *), (char *)tcp_saveipgen, sizeof(struct ip6_hdr));
+ else
+#endif
+ bcopy(mtod(m, char *), (char *)tcp_saveipgen, sizeof(struct ip));
+ tcp_savetcp = *th;
+ }
#endif
thflags = th->th_flags;
inc = &tp->t_inpcb->inp_inc;
diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c
index fea54cdcc5cb..f979649ca608 100644
--- a/sys/netinet/tcp_output.c
+++ b/sys/netinet/tcp_output.c
@@ -1430,26 +1430,6 @@ send:
hhook_run_tcp_est_out(tp, th, &to, len, tso);
#endif
-#ifdef TCPDEBUG
- /*
- * Trace.
- */
- if (so->so_options & SO_DEBUG) {
- u_short save = 0;
-#ifdef INET6
- if (!isipv6)
-#endif
- {
- save = ipov->ih_len;
- ipov->ih_len = htons(m->m_pkthdr.len /* - hdrlen + (th->th_off << 2) */);
- }
- tcp_trace(TA_OUTPUT, tp->t_state, tp, mtod(m, void *), th, 0);
-#ifdef INET6
- if (!isipv6)
-#endif
- ipov->ih_len = save;
- }
-#endif /* TCPDEBUG */
TCP_PROBE3(debug__output, tp, th, m);
/* We're getting ready to send; log now. */
@@ -1502,6 +1482,10 @@ send:
/* Save packet, if requested. */
tcp_pcap_add(th, m, &(tp->t_outpkts));
#endif
+#ifdef TCPDEBUG
+ if (so->so_options & SO_DEBUG)
+ tcp_trace(TA_OUTPUT, tp->t_state, tp, (void *)ip6, th, 0);
+#endif /* TCPDEBUG */
/* TODO: IPv6 IP6TOS_ECT bit on */
error = ip6_output(m, tp->t_inpcb->in6p_outputopts,
@@ -1549,6 +1533,10 @@ send:
/* Save packet, if requested. */
tcp_pcap_add(th, m, &(tp->t_outpkts));
#endif
+#ifdef TCPDEBUG
+ if (so->so_options & SO_DEBUG)
+ tcp_trace(TA_OUTPUT, tp->t_state, tp, (void *)ip, th, 0);
+#endif /* TCPDEBUG */
error = ip_output(m, tp->t_inpcb->inp_options, &tp->t_inpcb->inp_route,
((so->so_options & SO_DONTROUTE) ? IP_ROUTETOIF : 0), 0,
diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c
index 4b00b686be32..21e6b66ff81c 100644
--- a/sys/netinet/tcp_timer.c
+++ b/sys/netinet/tcp_timer.c
@@ -266,8 +266,12 @@ tcp_timer_delack(void *xtp)
struct epoch_tracker et;
struct tcpcb *tp = xtp;
struct inpcb *inp;
- CURVNET_SET(tp->t_vnet);
+#ifdef TCPDEBUG
+ int ostate;
+ ostate = tp->t_state;
+#endif
+ CURVNET_SET(tp->t_vnet);
inp = tp->t_inpcb;
KASSERT(inp != NULL, ("%s: tp %p tp->t_inpcb == NULL", __func__, tp));
INP_WLOCK(inp);
@@ -287,6 +291,11 @@ tcp_timer_delack(void *xtp)
TCPSTAT_INC(tcps_delack);
NET_EPOCH_ENTER(et);
(void) tp->t_fb->tfb_tcp_output(tp);
+#ifdef TCPDEBUG
+ if (inp->inp_socket->so_options & SO_DEBUG)
+ tcp_trace(TA_USER, ostate, tp, (void *)0, (struct tcphdr *)0,
+ (TCPT_DELACK << 8) | PRU_FASTTIMO);
+#endif
INP_WUNLOCK(inp);
NET_EPOCH_EXIT(et);
CURVNET_RESTORE();
@@ -380,7 +389,7 @@ tcp_timer_2msl(void *xtp)
#ifdef TCPDEBUG
if (tp != NULL && (tp->t_inpcb->inp_socket->so_options & SO_DEBUG))
tcp_trace(TA_USER, ostate, tp, (void *)0, (struct tcphdr *)0,
- PRU_SLOWTIMO);
+ (TCPT_2MSL << 8) | PRU_SLOWTIMO);
#endif
TCP_PROBE2(debug__user, tp, PRU_SLOWTIMO);
@@ -502,7 +511,7 @@ dropit:
#ifdef TCPDEBUG
if (tp != NULL && (tp->t_inpcb->inp_socket->so_options & SO_DEBUG))
tcp_trace(TA_USER, ostate, tp, (void *)0, (struct tcphdr *)0,
- PRU_SLOWTIMO);
+ (TCPT_KEEP << 8) | PRU_SLOWTIMO);
#endif
TCP_PROBE2(debug__user, tp, PRU_SLOWTIMO);
NET_EPOCH_EXIT(et);
@@ -592,7 +601,8 @@ tcp_timer_persist(void *xtp)
#ifdef TCPDEBUG
if (tp != NULL && tp->t_inpcb->inp_socket->so_options & SO_DEBUG)
- tcp_trace(TA_USER, ostate, tp, NULL, NULL, PRU_SLOWTIMO);
+ tcp_trace(TA_USER, ostate, tp, NULL, NULL,
+ (TCPT_PERSIST << 8) | PRU_SLOWTIMO);
#endif
TCP_PROBE2(debug__user, tp, PRU_SLOWTIMO);
INP_WUNLOCK(inp);
@@ -875,7 +885,7 @@ tcp_timer_rexmt(void * xtp)
#ifdef TCPDEBUG
if (tp != NULL && (tp->t_inpcb->inp_socket->so_options & SO_DEBUG))
tcp_trace(TA_USER, ostate, tp, (void *)0, (struct tcphdr *)0,
- PRU_SLOWTIMO);
+ (TCPT_REXMT << 8) | PRU_SLOWTIMO);
#endif
TCP_PROBE2(debug__user, tp, PRU_SLOWTIMO);
INP_WUNLOCK(inp);
diff --git a/sys/netinet/tcp_timer.h b/sys/netinet/tcp_timer.h
index 316b76e50f7e..d0bc74669123 100644
--- a/sys/netinet/tcp_timer.h
+++ b/sys/netinet/tcp_timer.h
@@ -35,6 +35,12 @@
#ifndef _NETINET_TCP_TIMER_H_
#define _NETINET_TCP_TIMER_H_
+#define TCPT_REXMT 0 /* retransmit */
+#define TCPT_PERSIST 1 /* retransmit persistance */
+#define TCPT_KEEP 2 /* keep alive */
+#define TCPT_2MSL 3 /* 2*msl quiet time timer */
+#define TCPT_DELACK 4 /* delay ack */
+
/*
* The TCPT_REXMT timer is used to force retransmissions.
* The TCP has the TCPT_REXMT timer set whenever segments
diff --git a/usr.sbin/trpt/trpt.8 b/usr.sbin/trpt/trpt.8
index 3c66f5afe761..8d674f76298b 100644
--- a/usr.sbin/trpt/trpt.8
+++ b/usr.sbin/trpt/trpt.8
@@ -28,13 +28,19 @@
.\" @(#)trpt.8 8.2 (Berkeley) 12/11/93
.\" $FreeBSD$
.\"
-.Dd February 15, 2018
+.Dd April 21, 2023
.Dt TRPT 8
.Os
.Sh NAME
.Nm trpt
.Nd transliterate protocol trace
.Sh SYNOPSIS
+To add support for this utility to the kernel, add the following line to the
+kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "options TCPDEBUG"
+.Ed
+.Pp
.Nm
.Op Fl a
.Op Fl f
@@ -44,12 +50,15 @@
.Oo
.Ar system Op Ar core
.Oc
+.Sh DEPRECATION NOTICE
+.Nm
+is deprecated and will not be available in
+.Fx 14.0
+and later.
.Sh DESCRIPTION
The
.Nm
-utility interrogates the buffer of
-.Tn TCP
-trace records created
+utility interrogates the buffer of TCP trace records created
when a socket is marked for
.Dq debugging
(see
@@ -58,11 +67,8 @@ and prints a readable description of these records.
When no options are supplied,
.Nm
prints all the trace records found in the system
-grouped according to
-.Tn TCP
-connection protocol control
-block
-.Pq Tn PCB .
+grouped according to TCP connection protocol control block
+.Pq PCB .
.Pp
The following options may be used to
alter this behavior:
@@ -142,3 +148,10 @@ but this is not saved in the trace record.
.Pp
The output format is inscrutable and should be described
here.
+.Pp
+It is not possible to use the
+.Nm
+utility if the following line is in the kernel config file:
+.Bd -ragged -offset indent
+.Cd "options TCPPCAP"
+.Ed
diff --git a/usr.sbin/trpt/trpt.c b/usr.sbin/trpt/trpt.c
index e8198f7d080e..b89a82c191d8 100644
--- a/usr.sbin/trpt/trpt.c
+++ b/usr.sbin/trpt/trpt.c
@@ -124,7 +124,7 @@ main(int argc, char **argv)
case 'p':
if (npcbs >= TCP_NDEBUG)
errx(1, "too many pcb's specified");
- (void)sscanf(optarg, "%x", (int *)&tcp_pcbs[npcbs++]);
+ (void)sscanf(optarg, "%lx", (long *)&tcp_pcbs[npcbs++]);
break;
case 's':
++sflag;
@@ -369,18 +369,16 @@ tcp_trace(short act, short ostate, struct tcpcb *tp, int family __unused,
len =
#ifdef INET6
- isipv6 ? ip6->ip6_plen :
+ isipv6 ? ntohs(ip6->ip6_plen) :
#endif
- ip4->ip_len;
+ ntohs(ip4->ip_len) - (ip4->ip_hl << 2);
win = th->th_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);
+ len -= th->th_off << 2;
if (len)
printf("[%lx..%lx)", (u_long)seq, (u_long)(seq + len));
else