aboutsummaryrefslogtreecommitdiff
path: root/cddl/usr.sbin/dwatch/libexec/tcp
diff options
context:
space:
mode:
Diffstat (limited to 'cddl/usr.sbin/dwatch/libexec/tcp')
-rw-r--r--cddl/usr.sbin/dwatch/libexec/tcp210
1 files changed, 210 insertions, 0 deletions
diff --git a/cddl/usr.sbin/dwatch/libexec/tcp b/cddl/usr.sbin/dwatch/libexec/tcp
new file mode 100644
index 000000000000..344cdb4ee6e8
--- /dev/null
+++ b/cddl/usr.sbin/dwatch/libexec/tcp
@@ -0,0 +1,210 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for dtrace_tcp(4) connections $
+# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Display local/remote TCP addresses/ports and bytes sent/received for TCP I/O
+#
+############################################################ PROBE
+
+case "$PROFILE" in
+tcp)
+ : ${PROBE:=$( echo \
+ tcp:::accept-established, \
+ tcp:::accept-refused, \
+ tcp:::connect-established, \
+ tcp:::connect-refused, \
+ tcp:::connect-request, \
+ tcp:::receive, \
+ tcp:::send, \
+ tcp:::state-change )} ;;
+tcp-accept)
+ : ${PROBE:=tcp:::accept-established, tcp:::accept-refused} ;;
+tcp-connect)
+ : ${PROBE:=$( echo \
+ tcp:::connect-established, \
+ tcp:::connect-refused, \
+ tcp:::connect-request )} ;;
+tcp-established)
+ : ${PROBE:=tcp:::accept-established, tcp:::connect-established} ;;
+tcp-init)
+ : ${PROBE:=$( echo \
+ tcp:::accept-established, \
+ tcp:::accept-refused, \
+ tcp:::connect-established, \
+ tcp:::connect-refused, \
+ tcp:::connect-request )} ;;
+tcp-io)
+ : ${PROBE:=tcp:::send, tcp:::receive} ;;
+tcp-refused)
+ : ${PROBE:=tcp:::accept-refused, tcp:::connect-refused} ;;
+tcp-status)
+ : ${PROBE:=$( echo \
+ tcp:::accept-established, \
+ tcp:::accept-refused, \
+ tcp:::connect-established, \
+ tcp:::connect-refused, \
+ tcp:::connect-request, \
+ tcp:::state-change )} ;;
+*)
+ : ${PROBE:=tcp:::${PROFILE#tcp-}}
+esac
+
+############################################################ ACTIONS
+
+exec 9<<EOF
+this int32_t from_state;
+this int32_t to_state;
+this string details;
+this string flow;
+this string local;
+this string remote;
+this u_char local6;
+this u_char remote6;
+this u_char slocal;
+this uint16_t lport;
+this uint16_t rport;
+this uint32_t length;
+
+inline string probeflow[string name] =
+ name == "accept-established" ? "<-" :
+ name == "accept-refused" ? "X-" :
+ name == "connect-refused" ? "-X" :
+ name == "connect-request" ? "-?" :
+ name == "receive" ? "<-" :
+ "->";
+
+inline u_char srclocal[string name] =
+ name == "accept-refused" ? 1 :
+ name == "connect-request" ? 1 :
+ name == "send" ? 1 :
+ 0;
+
+/*
+ * TCPSTATES from <sys/netinet/tcp_fsm.h> used by netstat(1)
+ */
+inline string tcpstate[int32_t state] =
+ state == TCPS_CLOSED ? "CLOSED" :
+ state == TCPS_LISTEN ? "LISTEN" :
+ state == TCPS_SYN_SENT ? "SYN_SENT" :
+ state == TCPS_SYN_RECEIVED ? "SYN_RCVD" :
+ state == TCPS_ESTABLISHED ? "ESTABLISHED" :
+ state == TCPS_CLOSE_WAIT ? "CLOSE_WAIT" :
+ state == TCPS_FIN_WAIT_1 ? "FIN_WAIT_1" :
+ state == TCPS_CLOSING ? "CLOSING" :
+ state == TCPS_LAST_ACK ? "LAST_ACK" :
+ state == TCPS_FIN_WAIT_2 ? "FIN_WAIT_2" :
+ state == TCPS_TIME_WAIT ? "TIME_WAIT" :
+ strjoin("UNKNOWN(", strjoin(lltostr(state), ")"));
+
+$PROBE /* probe ID $ID */
+{${TRACE:+
+ printf("<$ID>");}
+ this->details = "";
+
+ /*
+ * dtrace_tcp(4)
+ */
+ this->flow = probeflow[probename];
+}
+
+tcp:::accept-established,
+tcp:::accept-refused,
+tcp:::connect-established,
+tcp:::connect-refused,
+tcp:::connect-request,
+tcp:::receive,
+tcp:::send /* probe ID $(( $ID + 1 )) */
+{${TRACE:+
+ printf("<$(( $ID + 1 ))>");
+}
+ /*
+ * dtrace_tcp(4)
+ */
+ this->slocal = srclocal[probename];
+
+ /*
+ * ipinfo_t *
+ */
+ this->local = this->slocal ? args[2]->ip_saddr : args[2]->ip_daddr;
+ this->remote = this->slocal ? args[2]->ip_daddr : args[2]->ip_saddr;
+
+ /*
+ * tcpinfo_t *
+ */
+ this->lport = this->slocal ? args[4]->tcp_sport : args[4]->tcp_dport;
+ this->rport = this->slocal ? args[4]->tcp_dport : args[4]->tcp_sport;
+
+ /*
+ * IPv6 support
+ */
+ this->local6 = strstr(this->local, ":") != NULL ? 1 : 0;
+ this->remote6 = strstr(this->remote, ":") != NULL ? 1 : 0;
+ this->local = strjoin(strjoin(this->local6 ? "[" : "",
+ this->local), this->local6 ? "]" : "");
+ this->remote = strjoin(strjoin(this->remote6 ? "[" : "",
+ this->remote), this->remote6 ? "]" : "");
+}
+
+tcp:::state-change /* probe ID $(( $ID + 2 )) */
+{${TRACE:+
+ printf("<$(( $ID + 2 ))>");
+}
+ /*
+ * tcpsinfo_t *
+ */
+ this->local = args[3]->tcps_laddr;
+ this->lport = (uint16_t)args[3]->tcps_lport;
+ this->remote = args[3]->tcps_raddr;
+ this->rport = (uint16_t)args[3]->tcps_rport;
+ this->to_state = (int32_t)args[3]->tcps_state;
+
+ /*
+ * tcplsinfo_t *
+ */
+ this->from_state = (int32_t)args[5]->tcps_state;
+
+ /* flow = "[from state]->[to state]" */
+ this->flow = strjoin(tcpstate[this->from_state],
+ strjoin("->", tcpstate[this->to_state]));
+}
+
+tcp:::send, tcp:::receive /* pribe ID $(( $ID + 3 )) */
+{${TRACE:+
+ printf("<$(( $ID + 3 ))>");}
+ this->length = (uint32_t)args[2]->ip_plength -
+ (uint8_t)args[4]->tcp_offset;
+
+ /* details = " <length> byte<s>" */
+ this->details = strjoin(
+ strjoin(" ", lltostr(this->length)),
+ strjoin(" byte", this->length == 1 ? "" : "s"));
+}
+EOF
+ACTIONS=$( cat <&9 )
+ID=$(( $ID + 4 ))
+
+############################################################ EVENT DETAILS
+
+if [ ! "$CUSTOM_DETAILS" ]; then
+exec 9<<EOF
+ /*
+ * Print details
+ */
+ printf("%s:%u %s %s:%u%s",
+ this->local, this->lport,
+ this->flow,
+ this->remote, this->rport,
+ this->details);
+EOF
+EVENT_DETAILS=$( cat <&9 )
+fi
+
+################################################################################
+# END
+################################################################################