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