xref: /illumos-gate/usr/src/cmd/dtrace/demo/tcp/tcptop.d (revision 9cd928fe)
1*9cd928feSAlan Maguire #!/usr/sbin/dtrace -s
2*9cd928feSAlan Maguire /*
3*9cd928feSAlan Maguire  * tcptop: display top TCP network packets by process.
4*9cd928feSAlan Maguire  *	Written using DTrace tcp Provider.
5*9cd928feSAlan Maguire  *
6*9cd928feSAlan Maguire  * Usage: dtrace -s tcptop.d [count] [interval]
7*9cd928feSAlan Maguire  *
8*9cd928feSAlan Maguire  * This analyses TCP network packets and prints the responsible PID plus
9*9cd928feSAlan Maguire  * standard details such as IP address and port. This captures traffic
10*9cd928feSAlan Maguire  * of newly created TCP connections that were established while this program
11*9cd928feSAlan Maguire  * was running along with traffic from existing connections. It can help
12*9cd928feSAlan Maguire  * identify which processes is causing TCP traffic.
13*9cd928feSAlan Maguire  *
14*9cd928feSAlan Maguire  * CDDL HEADER START
15*9cd928feSAlan Maguire  *
16*9cd928feSAlan Maguire  * The contents of this file are subject to the terms of the
17*9cd928feSAlan Maguire  * Common Development and Distribution License (the "License").
18*9cd928feSAlan Maguire  * You may not use this file except in compliance with the License.
19*9cd928feSAlan Maguire  *
20*9cd928feSAlan Maguire  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
21*9cd928feSAlan Maguire  * or http://www.opensolaris.org/os/licensing.
22*9cd928feSAlan Maguire  * See the License for the specific language governing permissions
23*9cd928feSAlan Maguire  * and limitations under the License.
24*9cd928feSAlan Maguire  *
25*9cd928feSAlan Maguire  * When distributing Covered Code, include this CDDL HEADER in each
26*9cd928feSAlan Maguire  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
27*9cd928feSAlan Maguire  * If applicable, add the following below this CDDL HEADER, with the
28*9cd928feSAlan Maguire  * fields enclosed by brackets "[]" replaced with your own identifying
29*9cd928feSAlan Maguire  * information: Portions Copyright [yyyy] [name of copyright owner]
30*9cd928feSAlan Maguire  *
31*9cd928feSAlan Maguire  * CDDL HEADER END
32*9cd928feSAlan Maguire  */
33*9cd928feSAlan Maguire /*
34*9cd928feSAlan Maguire  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
35*9cd928feSAlan Maguire  *
36*9cd928feSAlan Maguire  * Portions Copyright 2010 Brendan Gregg
37*9cd928feSAlan Maguire  */
38*9cd928feSAlan Maguire 
39*9cd928feSAlan Maguire #pragma D option quiet
40*9cd928feSAlan Maguire #pragma D option defaultargs
41*9cd928feSAlan Maguire #pragma D option switchrate=10hz
42*9cd928feSAlan Maguire 
43*9cd928feSAlan Maguire /*
44*9cd928feSAlan Maguire  * Print header
45*9cd928feSAlan Maguire  */
46*9cd928feSAlan Maguire dtrace:::BEGIN
47*9cd928feSAlan Maguire {
48*9cd928feSAlan Maguire 	/* starting values */
49*9cd928feSAlan Maguire 	counts = $1 ? $1 : 10;
50*9cd928feSAlan Maguire 	secs = $2 ? $2 : 5;
51*9cd928feSAlan Maguire 	TCP_out = 0;
52*9cd928feSAlan Maguire 	TCP_in = 0;
53*9cd928feSAlan Maguire 
54*9cd928feSAlan Maguire 	printf("Sampling... Please wait.\n");
55*9cd928feSAlan Maguire }
56*9cd928feSAlan Maguire 
57*9cd928feSAlan Maguire 
58*9cd928feSAlan Maguire tcp:::send
59*9cd928feSAlan Maguire / args[1]->cs_pid != -1 /
60*9cd928feSAlan Maguire {
61*9cd928feSAlan Maguire 	@out[args[1]->cs_zoneid, args[1]->cs_pid, args[2]->ip_saddr,
62*9cd928feSAlan Maguire 	    args[4]->tcp_sport, args[2]->ip_daddr, args[4]->tcp_dport] =
63*9cd928feSAlan Maguire 	    sum(args[2]->ip_plength - args[4]->tcp_offset);
64*9cd928feSAlan Maguire }
65*9cd928feSAlan Maguire 
66*9cd928feSAlan Maguire tcp:::receive
67*9cd928feSAlan Maguire / args[1]->cs_pid != -1 /
68*9cd928feSAlan Maguire {
69*9cd928feSAlan Maguire 	@out[args[1]->cs_zoneid, args[1]->cs_pid, args[2]->ip_daddr,
70*9cd928feSAlan Maguire 	    args[4]->tcp_dport, args[2]->ip_saddr, args[4]->tcp_sport] =
71*9cd928feSAlan Maguire 	    sum(args[2]->ip_plength - args[4]->tcp_offset);
72*9cd928feSAlan Maguire }
73*9cd928feSAlan Maguire 
74*9cd928feSAlan Maguire /*
75*9cd928feSAlan Maguire  * TCP Systemwide Stats
76*9cd928feSAlan Maguire  */
77*9cd928feSAlan Maguire mib:::tcpOutDataBytes       { TCP_out += args[0]; }
78*9cd928feSAlan Maguire mib:::tcpRetransBytes       { TCP_out += args[0]; }
79*9cd928feSAlan Maguire mib:::tcpInDataInorderBytes { TCP_in  += args[0]; }
80*9cd928feSAlan Maguire mib:::tcpInDataDupBytes     { TCP_in  += args[0]; }
81*9cd928feSAlan Maguire mib:::tcpInDataUnorderBytes { TCP_in  += args[0]; }
82*9cd928feSAlan Maguire 
83*9cd928feSAlan Maguire profile:::tick-1sec
84*9cd928feSAlan Maguire /secs != 0/
85*9cd928feSAlan Maguire {
86*9cd928feSAlan Maguire 	secs--;
87*9cd928feSAlan Maguire }
88*9cd928feSAlan Maguire 
89*9cd928feSAlan Maguire /*
90*9cd928feSAlan Maguire  * Print Report
91*9cd928feSAlan Maguire  */
92*9cd928feSAlan Maguire profile:::tick-1sec
93*9cd928feSAlan Maguire /secs == 0/
94*9cd928feSAlan Maguire {
95*9cd928feSAlan Maguire 	/* fetch 1 min load average */
96*9cd928feSAlan Maguire 	this->load1a  = `hp_avenrun[0] / 65536;
97*9cd928feSAlan Maguire 	this->load1b  = ((`hp_avenrun[0] % 65536) * 100) / 65536;
98*9cd928feSAlan Maguire 
99*9cd928feSAlan Maguire 	/* convert TCP counters to Kb */
100*9cd928feSAlan Maguire 	TCP_out /= 1024;
101*9cd928feSAlan Maguire 	TCP_in  /= 1024;
102*9cd928feSAlan Maguire 
103*9cd928feSAlan Maguire 	/* print status */
104*9cd928feSAlan Maguire 	printf("%Y,  load: %d.%02d,  TCPin: %6d Kb,  TCPout: %6d Kb\n\n",
105*9cd928feSAlan Maguire 	    walltimestamp, this->load1a, this->load1b, TCP_in, TCP_out);
106*9cd928feSAlan Maguire 
107*9cd928feSAlan Maguire 	/* print headers */
108*9cd928feSAlan Maguire 	printf("%6s %6s %-15s %5s %-15s %5s %9s\n",
109*9cd928feSAlan Maguire 	    "ZONE", "PID", "LADDR", "LPORT", "RADDR", "RPORT", "SIZE");
110*9cd928feSAlan Maguire 
111*9cd928feSAlan Maguire 	/* print data */
112*9cd928feSAlan Maguire 	printa("%6d %6d %-15s %5d %-15s %5d %@9d\n", @out);
113*9cd928feSAlan Maguire 	printf("\n");
114*9cd928feSAlan Maguire 
115*9cd928feSAlan Maguire 	/* clear data */
116*9cd928feSAlan Maguire 	trunc(@out);
117*9cd928feSAlan Maguire 	TCP_in = 0;
118*9cd928feSAlan Maguire 	TCP_out = 0;
119*9cd928feSAlan Maguire 	secs = 5;
120*9cd928feSAlan Maguire 	counts--;
121*9cd928feSAlan Maguire }
122*9cd928feSAlan Maguire 
123*9cd928feSAlan Maguire /*
124*9cd928feSAlan Maguire  * End of program
125*9cd928feSAlan Maguire  */
126*9cd928feSAlan Maguire profile:::tick-1sec
127*9cd928feSAlan Maguire /counts == 0/
128*9cd928feSAlan Maguire {
129*9cd928feSAlan Maguire 	exit(0);
130*9cd928feSAlan Maguire }
131*9cd928feSAlan Maguire 
132*9cd928feSAlan Maguire /*
133*9cd928feSAlan Maguire  * Cleanup for Ctrl-C
134*9cd928feSAlan Maguire  */
135*9cd928feSAlan Maguire dtrace:::END
136*9cd928feSAlan Maguire {
137*9cd928feSAlan Maguire 	trunc(@out);
138*9cd928feSAlan Maguire }
139