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