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