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