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