diff options
Diffstat (limited to 'cddl/usr.sbin/dwatch/libexec/tcp')
-rw-r--r-- | cddl/usr.sbin/dwatch/libexec/tcp | 210 |
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 +################################################################################ |