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 */ 46dtrace:::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 58tcp:::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 66tcp:::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 */ 77mib:::tcpOutDataBytes { TCP_out += args[0]; } 78mib:::tcpRetransBytes { TCP_out += args[0]; } 79mib:::tcpInDataInorderBytes { TCP_in += args[0]; } 80mib:::tcpInDataDupBytes { TCP_in += args[0]; } 81mib:::tcpInDataUnorderBytes { TCP_in += args[0]; } 82 83profile:::tick-1sec 84/secs != 0/ 85{ 86 secs--; 87} 88 89/* 90 * Print Report 91 */ 92profile:::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 */ 126profile:::tick-1sec 127/counts == 0/ 128{ 129 exit(0); 130} 131 132/* 133 * Cleanup for Ctrl-C 134 */ 135dtrace:::END 136{ 137 trunc(@out); 138} 139