1# -*- tab-width: 4 -*- ;; Emacs 2# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM 3############################################################ IDENT(1) 4# 5# $Title: dwatch(8) module for dtrace_tcp(4) connections $ 6# $Copyright: 2014-2018 Devin Teske. All rights reserved. $ 7# 8############################################################ DESCRIPTION 9# 10# Display local/remote TCP addresses/ports and bytes sent/received for TCP I/O 11# 12############################################################ PROBE 13 14case "$PROFILE" in 15tcp) 16 : ${PROBE:=$( echo \ 17 tcp:::accept-established, \ 18 tcp:::accept-refused, \ 19 tcp:::connect-established, \ 20 tcp:::connect-refused, \ 21 tcp:::connect-request, \ 22 tcp:::receive, \ 23 tcp:::send, \ 24 tcp:::state-change )} ;; 25tcp-accept) 26 : ${PROBE:=tcp:::accept-established, tcp:::accept-refused} ;; 27tcp-connect) 28 : ${PROBE:=$( echo \ 29 tcp:::connect-established, \ 30 tcp:::connect-refused, \ 31 tcp:::connect-request )} ;; 32tcp-established) 33 : ${PROBE:=tcp:::accept-established, tcp:::connect-established} ;; 34tcp-init) 35 : ${PROBE:=$( echo \ 36 tcp:::accept-established, \ 37 tcp:::accept-refused, \ 38 tcp:::connect-established, \ 39 tcp:::connect-refused, \ 40 tcp:::connect-request )} ;; 41tcp-io) 42 : ${PROBE:=tcp:::send, tcp:::receive} ;; 43tcp-refused) 44 : ${PROBE:=tcp:::accept-refused, tcp:::connect-refused} ;; 45tcp-status) 46 : ${PROBE:=$( echo \ 47 tcp:::accept-established, \ 48 tcp:::accept-refused, \ 49 tcp:::connect-established, \ 50 tcp:::connect-refused, \ 51 tcp:::connect-request, \ 52 tcp:::state-change )} ;; 53*) 54 : ${PROBE:=tcp:::${PROFILE#tcp-}} 55esac 56 57############################################################ ACTIONS 58 59exec 9<<EOF 60this int32_t from_state; 61this int32_t to_state; 62this string details; 63this string flow; 64this string local; 65this string remote; 66this u_char local6; 67this u_char remote6; 68this u_char slocal; 69this uint16_t lport; 70this uint16_t rport; 71this uint32_t length; 72 73inline string probeflow[string name] = 74 name == "accept-established" ? "<-" : 75 name == "accept-refused" ? "X-" : 76 name == "connect-refused" ? "-X" : 77 name == "connect-request" ? "-?" : 78 name == "receive" ? "<-" : 79 "->"; 80 81inline u_char srclocal[string name] = 82 name == "accept-refused" ? 1 : 83 name == "connect-request" ? 1 : 84 name == "send" ? 1 : 85 0; 86 87/* 88 * TCPSTATES from <sys/netinet/tcp_fsm.h> used by netstat(1) 89 */ 90inline string tcpstate[int32_t state] = 91 state == TCPS_CLOSED ? "CLOSED" : 92 state == TCPS_LISTEN ? "LISTEN" : 93 state == TCPS_SYN_SENT ? "SYN_SENT" : 94 state == TCPS_SYN_RECEIVED ? "SYN_RCVD" : 95 state == TCPS_ESTABLISHED ? "ESTABLISHED" : 96 state == TCPS_CLOSE_WAIT ? "CLOSE_WAIT" : 97 state == TCPS_FIN_WAIT_1 ? "FIN_WAIT_1" : 98 state == TCPS_CLOSING ? "CLOSING" : 99 state == TCPS_LAST_ACK ? "LAST_ACK" : 100 state == TCPS_FIN_WAIT_2 ? "FIN_WAIT_2" : 101 state == TCPS_TIME_WAIT ? "TIME_WAIT" : 102 strjoin("UNKNOWN(", strjoin(lltostr(state), ")")); 103 104$PROBE /* probe ID $ID */ 105{${TRACE:+ 106 printf("<$ID>");} 107 this->details = ""; 108 109 /* 110 * dtrace_tcp(4) 111 */ 112 this->flow = probeflow[probename]; 113} 114 115tcp:::accept-established, 116tcp:::accept-refused, 117tcp:::connect-established, 118tcp:::connect-refused, 119tcp:::connect-request, 120tcp:::receive, 121tcp:::send /* probe ID $(( $ID + 1 )) */ 122{${TRACE:+ 123 printf("<$(( $ID + 1 ))>"); 124} 125 /* 126 * dtrace_tcp(4) 127 */ 128 this->slocal = srclocal[probename]; 129 130 /* 131 * ipinfo_t * 132 */ 133 this->local = this->slocal ? args[2]->ip_saddr : args[2]->ip_daddr; 134 this->remote = this->slocal ? args[2]->ip_daddr : args[2]->ip_saddr; 135 136 /* 137 * tcpinfo_t * 138 */ 139 this->lport = this->slocal ? args[4]->tcp_sport : args[4]->tcp_dport; 140 this->rport = this->slocal ? args[4]->tcp_dport : args[4]->tcp_sport; 141 142 /* 143 * IPv6 support 144 */ 145 this->local6 = strstr(this->local, ":") != NULL ? 1 : 0; 146 this->remote6 = strstr(this->remote, ":") != NULL ? 1 : 0; 147 this->local = strjoin(strjoin(this->local6 ? "[" : "", 148 this->local), this->local6 ? "]" : ""); 149 this->remote = strjoin(strjoin(this->remote6 ? "[" : "", 150 this->remote), this->remote6 ? "]" : ""); 151} 152 153tcp:::state-change /* probe ID $(( $ID + 2 )) */ 154{${TRACE:+ 155 printf("<$(( $ID + 2 ))>"); 156} 157 /* 158 * tcpsinfo_t * 159 */ 160 this->local = args[3]->tcps_laddr; 161 this->lport = (uint16_t)args[3]->tcps_lport; 162 this->remote = args[3]->tcps_raddr; 163 this->rport = (uint16_t)args[3]->tcps_rport; 164 this->to_state = (int32_t)args[3]->tcps_state; 165 166 /* 167 * tcplsinfo_t * 168 */ 169 this->from_state = (int32_t)args[5]->tcps_state; 170 171 /* flow = "[from state]->[to state]" */ 172 this->flow = strjoin(tcpstate[this->from_state], 173 strjoin("->", tcpstate[this->to_state])); 174} 175 176tcp:::send, tcp:::receive /* pribe ID $(( $ID + 3 )) */ 177{${TRACE:+ 178 printf("<$(( $ID + 3 ))>");} 179 this->length = (uint32_t)args[2]->ip_plength - 180 (uint8_t)args[4]->tcp_offset; 181 182 /* details = " <length> byte<s>" */ 183 this->details = strjoin( 184 strjoin(" ", lltostr(this->length)), 185 strjoin(" byte", this->length == 1 ? "" : "s")); 186} 187EOF 188ACTIONS=$( cat <&9 ) 189ID=$(( $ID + 4 )) 190 191############################################################ EVENT DETAILS 192 193if [ ! "$CUSTOM_DETAILS" ]; then 194exec 9<<EOF 195 /* 196 * Print details 197 */ 198 printf("%s:%u %s %s:%u%s", 199 this->local, this->lport, 200 this->flow, 201 this->remote, this->rport, 202 this->details); 203EOF 204EVENT_DETAILS=$( cat <&9 ) 205fi 206 207################################################################################ 208# END 209################################################################################ 210