Changeset View
Changeset View
Standalone View
Standalone View
head/cddl/usr.sbin/dwatch/libexec/tcp
Property | Old Value | New Value |
---|---|---|
svn:keywords | null | FreeBSD=%H \ No newline at end of property |
# -*- 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 | |||||
############################################################ GLOBALS | |||||
# | |||||
# This profile does not support these dwatch features | |||||
# NB: They are disabled here so they have no effect when profile is loaded | |||||
# | |||||
unset EXECNAME # -k name | |||||
unset EXECREGEX # -z regex | |||||
unset GROUP # -g group | |||||
unset PID # -p pid | |||||
unset PSARGS # affects -d | |||||
unset PSTREE # -R | |||||
unset USER # -u user | |||||
############################################################ 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 TAG | |||||
exec 9<<EOF | |||||
printf("%s: ", "$PROFILE"); | |||||
EOF | |||||
EVENT_TAG=$( cat <&9 ) | |||||
############################################################ EVENT DETAILS | |||||
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 ) | |||||
################################################################################ | |||||
# END | |||||
################################################################################ |