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