1332866Sdteske# -*- tab-width: 4 -*- ;; Emacs 2332866Sdteske# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM 3332866Sdteske############################################################ IDENT(1) 4332866Sdteske# 5332866Sdteske# $Title: dwatch(8) module for send(2)/recv(2) $ 6332866Sdteske# $Copyright: 2014-2018 Devin Teske. All rights reserved. $ 7332866Sdteske# $FreeBSD: stable/11/cddl/usr.sbin/dwatch/libexec/sendrecv 333617 2018-05-15 00:00:44Z dteske $ 8332866Sdteske# 9332866Sdteske############################################################ DESCRIPTION 10332866Sdteske# 11332866Sdteske# Print details from send(2)/recv(2) 12332866Sdteske# 13332866Sdteske############################################################ PROBE 14332866Sdteske 15332866Sdteskecase "$PROFILE" in 16332866Sdteskesendrecv) 17332866Sdteske : ${PROBE:=$( echo \ 18332866Sdteske syscall::recvfrom:return, \ 19332866Sdteske syscall::recvmsg:return, \ 20332866Sdteske syscall::sendmsg:entry, \ 21332866Sdteske syscall::sendto:entry )} ;; 22332866Sdteskesend) 23332866Sdteske : ${PROBE:=$( echo \ 24332866Sdteske syscall::sendmsg:entry, \ 25332866Sdteske syscall::sendto:entry )} ;; 26332866Sdteskerecv) 27332866Sdteske : ${PROBE:=$( echo \ 28332866Sdteske syscall::recvfrom:return, \ 29332866Sdteske syscall::recvmsg:return )} ;; 30333617Sdteskerecv*) 31333617Sdteske : ${PROBE:=syscall::$PROFILE:return} ;; 32332866Sdteske*) 33333617Sdteske : ${PROBE:=syscall::$PROFILE:entry} 34332866Sdteskeesac 35332866Sdteske 36332866Sdteske############################################################ EVENT ACTION 37332866Sdteske 38332866Sdteske#[ "$CUSTOM_TEST" ] || EVENT_TEST="this->from != NULL" 39332866Sdteske 40332866Sdteske############################################################ ACTIONS 41332866Sdteske 42332866Sdteskeexec 9<<EOF 43332866Sdtesketypedef struct sainfo { 44332866Sdteske sa_family_t sa_family; 45332866Sdteske uint16_t port; 46332866Sdteske string addr; 47332866Sdteske string family; 48332866Sdteske} sainfo_t; 49332866Sdteske 50332866Sdteske/* 51332866Sdteske * Address families from <sys/socket.h> 52332866Sdteske */ 53332866Sdteske#pragma D binding "1.13" address_family_string 54332866Sdteskeinline string address_family_string[sa_family_t af] = 55332866Sdteske af == AF_UNSPEC ? "AF_UNSPEC" : 56332866Sdteske af == AF_LOCAL ? "AF_UNIX" : 57332866Sdteske af == AF_UNIX ? "AF_UNIX" : 58332866Sdteske af == AF_INET ? "AF_INET" : 59332866Sdteske af == AF_IMPLINK ? "AF_IMPLINK" : 60332866Sdteske af == AF_PUP ? "AF_PUP" : 61332866Sdteske af == AF_CHAOS ? "AF_CHAOS" : 62332866Sdteske af == AF_NETBIOS ? "AF_NETBIOS" : 63332866Sdteske af == AF_ISO ? "AF_ISO" : 64332866Sdteske af == AF_OSI ? "AF_ISO" : 65332866Sdteske af == AF_ECMA ? "AF_ECMA" : 66332866Sdteske af == AF_DATAKIT ? "AF_DATAKIT" : 67332866Sdteske af == AF_CCITT ? "AF_CCITT" : 68332866Sdteske af == AF_SNA ? "AF_SNA" : 69332866Sdteske af == AF_DECnet ? "AF_DECnet" : 70332866Sdteske af == AF_DLI ? "AF_DLI" : 71332866Sdteske af == AF_LAT ? "AF_LAT" : 72332866Sdteske af == AF_HYLINK ? "AF_HYLINK" : 73332866Sdteske af == AF_APPLETALK ? "AF_APPLETALK" : 74332866Sdteske af == AF_ROUTE ? "AF_ROUTE" : 75332866Sdteske af == AF_LINK ? "AF_LINK" : 76332866Sdteske af == pseudo_AF_XTP ? "pseudo_AF_XTP" : 77332866Sdteske af == AF_COIP ? "AF_COIP" : 78332866Sdteske af == AF_CNT ? "AF_CNT" : 79332866Sdteske af == pseudo_AF_RTIP ? "pseudo_AF_RTIP" : 80332866Sdteske af == AF_IPX ? "AF_IPX" : 81332866Sdteske af == AF_SIP ? "AF_SIP" : 82332866Sdteske af == pseudo_AF_PIP ? "pseudo_AF_PIP" : 83332866Sdteske af == AF_ISDN ? "AF_ISDN" : 84332866Sdteske af == AF_E164 ? "AF_ISDN" : 85332866Sdteske af == pseudo_AF_KEY ? "pseudo_AF_KEY" : 86332866Sdteske af == AF_INET6 ? "AF_INET6" : 87332866Sdteske af == AF_NATM ? "AF_NATM" : 88332866Sdteske af == AF_ATM ? "AF_ATM" : 89332866Sdteske af == pseudo_AF_HDRCMPLT ? "pseudo_AF_HDRCMPLT" : 90332866Sdteske af == AF_NETGRAPH ? "AF_NETGRAPH" : 91332866Sdteske af == AF_SLOW ? "AF_SLOW" : 92332866Sdteske af == AF_SCLUSTER ? "AF_SCLUSTER" : 93332866Sdteske af == AF_ARP ? "AF_ARP" : 94332866Sdteske af == AF_BLUETOOTH ? "AF_BLUETOOTH" : 95332866Sdteske af == AF_IEEE80211 ? "AF_IEEE80211" : 96332866Sdteske af == AF_INET_SDP ? "AF_INET_SDP" : 97332866Sdteske af == AF_INET6_SDP ? "AF_INET6_SDP" : 98332866Sdteske af == AF_MAX ? "AF_MAX" : 99332866Sdteske strjoin("AF_UNKNOWN(", strjoin(lltostr(af), ")")); 100332866Sdteske 101332866Sdteske#pragma D binding "1.13" sa_data_size 102332866Sdteskeinline int sa_data_size = 14; 103333617Sdteske#pragma D binding "1.13" sa_dummy_data 104333617Sdteskeinline char *sa_dummy_data = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; 105332866Sdteske 106332866Sdteske#pragma D binding "1.13" sa_data_addr 107332866Sdteskeinline string sa_data_addr[sa_family_t af, char data[sa_data_size]] = 108332866Sdteske af == AF_INET ? strjoin( 109332866Sdteske strjoin(strjoin(lltostr(data[2] & 0xFF), "."), 110332866Sdteske strjoin(lltostr(data[3] & 0xFF), ".") 111332866Sdteske ), 112332866Sdteske strjoin(strjoin(lltostr(data[4] & 0xFF), "."), 113332866Sdteske lltostr(data[5] & 0xFF)) 114332866Sdteske ) : 115332866Sdteske ""; 116332866Sdteske 117332866Sdteske#pragma D binding "1.13" sa_data_port 118332866Sdteskeinline uint16_t sa_data_port[sa_family_t af, char data[sa_data_size]] = 119332866Sdteske af == AF_INET ? (data[0] << 8) + data[1] : 120332866Sdteske 0; 121332866Sdteske 122332866Sdteske#pragma D binding "1.13" translator 123332866Sdtesketranslator sainfo_t < struct sockaddr *SA > { 124333617Sdteske sa_family = SA == NULL ? 0 : SA->sa_family; 125333617Sdteske family = address_family_string[SA == NULL ? 0 : SA->sa_family]; 126333617Sdteske addr = SA == NULL ? 127333617Sdteske sa_data_addr[0, sa_dummy_data] : 128333617Sdteske sa_data_addr[SA->sa_family, SA->sa_data]; 129333617Sdteske port = SA == NULL ? 130333617Sdteske sa_data_port[0, sa_dummy_data] : 131333617Sdteske sa_data_port[SA->sa_family, SA->sa_data]; 132332866Sdteske}; 133332866Sdteske 134332866Sdteskethis sainfo_t sainfo; 135332866Sdteskethis ssize_t nbytes; 136332866Sdteskethis string details; 137332866Sdteskethis string flow; 138332866Sdteskethis struct msghdr * msghdr; 139332866Sdteskethis struct sockaddr * sa; 140332866Sdteske 141332866Sdteskeinline string probeflow[string func] = 142332866Sdteske func == "recvfrom" ? "<-" : 143332866Sdteske func == "recvmsg" ? "<-" : 144332866Sdteske func == "recvmmsg" ? "<-" : 145332866Sdteske "->"; 146332866Sdteske 147332866Sdteskeinline string af_details[sa_family_t af, string addr, uint16_t port] = 148332866Sdteske af == AF_INET ? strjoin(addr, strjoin(":", lltostr(port))) : 149332866Sdteske ""; 150332866Sdteske 151332866Sdteske$PROBE /* probe ID $ID */ 152332866Sdteske{${TRACE:+ 153332866Sdteske printf("<$ID>");} 154332866Sdteske this->details = ""; 155332866Sdteske this->flow = probeflow[probefunc]; 156332866Sdteske} 157332866Sdteske 158332866Sdteskesyscall::recvfrom:entry /* probe ID $(( $ID + 1 )) */ 159332866Sdteske{${TRACE:+ 160332866Sdteske printf("<$(( $ID + 1 ))>");} 161333617Sdteske this->sainfo = xlate <sainfo_t> ((struct sockaddr *)(args[4] == NULL ? 162333617Sdteske NULL : copyin(arg4, sizeof(struct sockaddr)))); 163332866Sdteske} 164332866Sdteske 165332866Sdteskesyscall::recvfrom:return /* probe ID $(( $ID + 2 )) */ 166332866Sdteske{${TRACE:+ 167332866Sdteske printf("<$(( $ID + 2 ))>");} 168332866Sdteske this->nbytes = arg0; 169332866Sdteske this->details = strjoin("from ", strjoin( 170332866Sdteske strjoin(this->sainfo.family, " "), 171332866Sdteske af_details[this->sainfo.sa_family, 172332866Sdteske this->sainfo.addr, this->sainfo.port])); 173332866Sdteske} 174332866Sdteske 175333617Sdteskesyscall::recvmsg:entry /* probe ID $(( $ID + 3 )) */ 176332866Sdteske{${TRACE:+ 177332866Sdteske printf("<$(( $ID + 3 ))>");} 178333617Sdteske this->sockaddr = (struct sockaddr *)arg1; 179333617Sdteske} 180333617Sdteske 181333617Sdteskesyscall::recvmsg:return /this->sockaddr != NULL/ /* probe ID $(( $ID + 4 )) */ 182333617Sdteske{${TRACE:+ 183333617Sdteske printf("<$(( $ID + 4 ))>");} 184332866Sdteske this->nbytes = arg0; 185333617Sdteske this->sainfo = xlate <sainfo_t> ((struct sockaddr *)this->sockaddr); 186333617Sdteske this->details = strjoin("sainfo=[", "]"); 187332866Sdteske} 188332866Sdteske 189332866Sdteskesyscall::sendmsg:entry /* probe ID $(( $ID + 5 )) */ 190332866Sdteske{${TRACE:+ 191332866Sdteske printf("<$(( $ID + 5 ))>");} 192332866Sdteske this->nbytes = arg2; 193332866Sdteske} 194332866Sdteske 195333617Sdteskesyscall::sendto:entry /* probe ID $(( $ID + 6 )) */ 196332866Sdteske{${TRACE:+ 197333617Sdteske printf("<$(( $ID + 6 ))>");} 198332866Sdteske this->nbytes = arg2; 199333617Sdteske this->sainfo = xlate <sainfo_t> ((struct sockaddr *)(arg4 == NULL ? 200333617Sdteske NULL : copyin(arg4, sizeof(struct sockaddr)))); 201332866Sdteske this->details = strjoin("to ", strjoin( 202332866Sdteske strjoin(this->sainfo.family, " "), 203332866Sdteske af_details[this->sainfo.sa_family, 204332866Sdteske this->sainfo.addr, this->sainfo.port])); 205332866Sdteske} 206332866SdteskeEOF 207332866SdteskeACTIONS=$( cat <&9 ) 208333617SdteskeID=$(( $ID + 7 )) 209332866Sdteske 210332866Sdteske############################################################ EVENT DETAILS 211332866Sdteske 212333617Sdteskeif [ ! "$CUSTOM_DETAILS" ]; then 213332866Sdteskeexec 9<<EOF 214332866Sdteske /* 215332866Sdteske * Print socket details 216332866Sdteske */ 217332866Sdteske printf("%s %d byte%s%s%s", 218332866Sdteske this->flow, 219332866Sdteske this->nbytes, 220332866Sdteske this->nbytes != 1 ? "s" : "", 221332866Sdteske this->details != "" ? " " : "", 222332866Sdteske this->details); 223332866SdteskeEOF 224332866SdteskeEVENT_DETAILS=$( cat <&9 ) 225333617Sdteskefi 226332866Sdteske 227332866Sdteske################################################################################ 228332866Sdteske# END 229332866Sdteske################################################################################ 230