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 send(2)/recv(2) $ 6# $Copyright: 2014-2018 Devin Teske. All rights reserved. $ 7# 8############################################################ DESCRIPTION 9# 10# Print details from send(2)/recv(2) 11# 12############################################################ PROBE 13 14case "$PROFILE" in 15sendrecv) 16 : ${PROBE:=$( echo \ 17 syscall::recvfrom:return, \ 18 syscall::recvmsg:return, \ 19 syscall::sendmsg:entry, \ 20 syscall::sendto:entry )} ;; 21send) 22 : ${PROBE:=$( echo \ 23 syscall::sendmsg:entry, \ 24 syscall::sendto:entry )} ;; 25recv) 26 : ${PROBE:=$( echo \ 27 syscall::recvfrom:return, \ 28 syscall::recvmsg:return )} ;; 29recv*) 30 : ${PROBE:=syscall::$PROFILE:return} ;; 31*) 32 : ${PROBE:=syscall::$PROFILE:entry} 33esac 34 35############################################################ EVENT ACTION 36 37#[ "$CUSTOM_TEST" ] || EVENT_TEST="this->from != NULL" 38 39############################################################ ACTIONS 40 41exec 9<<EOF 42typedef struct sainfo { 43 sa_family_t sa_family; 44 uint16_t port; 45 string addr; 46 string family; 47} sainfo_t; 48 49/* 50 * Address families from <sys/socket.h> 51 */ 52#pragma D binding "1.13" address_family_string 53inline string address_family_string[sa_family_t af] = 54 af == AF_UNSPEC ? "AF_UNSPEC" : 55 af == AF_LOCAL ? "AF_UNIX" : 56 af == AF_UNIX ? "AF_UNIX" : 57 af == AF_INET ? "AF_INET" : 58 af == AF_IMPLINK ? "AF_IMPLINK" : 59 af == AF_PUP ? "AF_PUP" : 60 af == AF_CHAOS ? "AF_CHAOS" : 61 af == AF_NETBIOS ? "AF_NETBIOS" : 62 af == AF_ISO ? "AF_ISO" : 63 af == AF_OSI ? "AF_ISO" : 64 af == AF_ECMA ? "AF_ECMA" : 65 af == AF_DATAKIT ? "AF_DATAKIT" : 66 af == AF_CCITT ? "AF_CCITT" : 67 af == AF_SNA ? "AF_SNA" : 68 af == AF_DECnet ? "AF_DECnet" : 69 af == AF_DLI ? "AF_DLI" : 70 af == AF_LAT ? "AF_LAT" : 71 af == AF_HYLINK ? "AF_HYLINK" : 72 af == AF_APPLETALK ? "AF_APPLETALK" : 73 af == AF_ROUTE ? "AF_ROUTE" : 74 af == AF_LINK ? "AF_LINK" : 75 af == pseudo_AF_XTP ? "pseudo_AF_XTP" : 76 af == AF_COIP ? "AF_COIP" : 77 af == AF_CNT ? "AF_CNT" : 78 af == pseudo_AF_RTIP ? "pseudo_AF_RTIP" : 79 af == AF_IPX ? "AF_IPX" : 80 af == AF_SIP ? "AF_SIP" : 81 af == pseudo_AF_PIP ? "pseudo_AF_PIP" : 82 af == AF_ISDN ? "AF_ISDN" : 83 af == AF_E164 ? "AF_ISDN" : 84 af == pseudo_AF_KEY ? "pseudo_AF_KEY" : 85 af == AF_INET6 ? "AF_INET6" : 86 af == AF_NATM ? "AF_NATM" : 87 af == AF_ATM ? "AF_ATM" : 88 af == pseudo_AF_HDRCMPLT ? "pseudo_AF_HDRCMPLT" : 89 af == AF_NETGRAPH ? "AF_NETGRAPH" : 90 af == AF_SLOW ? "AF_SLOW" : 91 af == AF_SCLUSTER ? "AF_SCLUSTER" : 92 af == AF_ARP ? "AF_ARP" : 93 af == AF_BLUETOOTH ? "AF_BLUETOOTH" : 94 af == AF_IEEE80211 ? "AF_IEEE80211" : 95 af == AF_INET_SDP ? "AF_INET_SDP" : 96 af == AF_INET6_SDP ? "AF_INET6_SDP" : 97 af == AF_MAX ? "AF_MAX" : 98 strjoin("AF_UNKNOWN(", strjoin(lltostr(af), ")")); 99 100#pragma D binding "1.13" sa_data_size 101inline int sa_data_size = 14; 102#pragma D binding "1.13" sa_dummy_data 103inline char *sa_dummy_data = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; 104 105#pragma D binding "1.13" sa_data_addr 106inline string sa_data_addr[sa_family_t af, char data[sa_data_size]] = 107 af == AF_INET ? strjoin( 108 strjoin(strjoin(lltostr(data[2] & 0xFF), "."), 109 strjoin(lltostr(data[3] & 0xFF), ".") 110 ), 111 strjoin(strjoin(lltostr(data[4] & 0xFF), "."), 112 lltostr(data[5] & 0xFF)) 113 ) : 114 ""; 115 116#pragma D binding "1.13" sa_data_port 117inline uint16_t sa_data_port[sa_family_t af, char data[sa_data_size]] = 118 af == AF_INET ? (data[0] << 8) + data[1] : 119 0; 120 121#pragma D binding "1.13" translator 122translator sainfo_t < struct sockaddr *SA > { 123 sa_family = SA == NULL ? 0 : SA->sa_family; 124 family = address_family_string[SA == NULL ? 0 : SA->sa_family]; 125 addr = SA == NULL ? 126 sa_data_addr[0, sa_dummy_data] : 127 sa_data_addr[SA->sa_family, SA->sa_data]; 128 port = SA == NULL ? 129 sa_data_port[0, sa_dummy_data] : 130 sa_data_port[SA->sa_family, SA->sa_data]; 131}; 132 133this sainfo_t sainfo; 134this ssize_t nbytes; 135this string details; 136this string flow; 137this struct msghdr * msghdr; 138this struct sockaddr * sa; 139 140inline string probeflow[string func] = 141 func == "recvfrom" ? "<-" : 142 func == "recvmsg" ? "<-" : 143 func == "recvmmsg" ? "<-" : 144 "->"; 145 146inline string af_details[sa_family_t af, string addr, uint16_t port] = 147 af == AF_INET ? strjoin(addr, strjoin(":", lltostr(port))) : 148 ""; 149 150$PROBE /* probe ID $ID */ 151{${TRACE:+ 152 printf("<$ID>");} 153 this->details = ""; 154 this->flow = probeflow[probefunc]; 155} 156 157syscall::recvfrom:entry /* probe ID $(( $ID + 1 )) */ 158{${TRACE:+ 159 printf("<$(( $ID + 1 ))>");} 160 this->sainfo = xlate <sainfo_t> ((struct sockaddr *)(args[4] == NULL ? 161 NULL : copyin(arg4, sizeof(struct sockaddr)))); 162} 163 164syscall::recvfrom:return /* probe ID $(( $ID + 2 )) */ 165{${TRACE:+ 166 printf("<$(( $ID + 2 ))>");} 167 this->nbytes = arg0; 168 this->details = strjoin("from ", strjoin( 169 strjoin(this->sainfo.family, " "), 170 af_details[this->sainfo.sa_family, 171 this->sainfo.addr, this->sainfo.port])); 172} 173 174syscall::recvmsg:entry /* probe ID $(( $ID + 3 )) */ 175{${TRACE:+ 176 printf("<$(( $ID + 3 ))>");} 177 this->sockaddr = (struct sockaddr *)arg1; 178} 179 180syscall::recvmsg:return /this->sockaddr != NULL/ /* probe ID $(( $ID + 4 )) */ 181{${TRACE:+ 182 printf("<$(( $ID + 4 ))>");} 183 this->nbytes = arg0; 184 this->sainfo = xlate <sainfo_t> ((struct sockaddr *)this->sockaddr); 185 this->details = strjoin("sainfo=[", "]"); 186} 187 188syscall::sendmsg:entry /* probe ID $(( $ID + 5 )) */ 189{${TRACE:+ 190 printf("<$(( $ID + 5 ))>");} 191 this->nbytes = arg2; 192} 193 194syscall::sendto:entry /* probe ID $(( $ID + 6 )) */ 195{${TRACE:+ 196 printf("<$(( $ID + 6 ))>");} 197 this->nbytes = arg2; 198 this->sainfo = xlate <sainfo_t> ((struct sockaddr *)(arg4 == NULL ? 199 NULL : copyin(arg4, sizeof(struct sockaddr)))); 200 this->details = strjoin("to ", strjoin( 201 strjoin(this->sainfo.family, " "), 202 af_details[this->sainfo.sa_family, 203 this->sainfo.addr, this->sainfo.port])); 204} 205EOF 206ACTIONS=$( cat <&9 ) 207ID=$(( $ID + 7 )) 208 209############################################################ EVENT DETAILS 210 211if [ ! "$CUSTOM_DETAILS" ]; then 212exec 9<<EOF 213 /* 214 * Print socket details 215 */ 216 printf("%s %d byte%s%s%s", 217 this->flow, 218 this->nbytes, 219 this->nbytes != 1 ? "s" : "", 220 this->details != "" ? " " : "", 221 this->details); 222EOF 223EVENT_DETAILS=$( cat <&9 ) 224fi 225 226################################################################################ 227# END 228################################################################################ 229