1 #!/usr/sbin/dtrace -s 2 /* 3 * udptop: display top UDP network packets by process. 4 * Written using DTrace udp Provider. 5 * 6 * Usage: dtrace -s udptop.d [count] [interval] 7 * 8 * This analyses UDP network packets and prints the responsible PID plus 9 * standard details such as IP address and port. This captures traffic 10 * of newly created UDP 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 UDP 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 /* 35 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 36 * 37 * Portions Copyright 2010 Brendan Gregg 38 */ 39 40 #pragma D option quiet 41 #pragma D option defaultargs 42 #pragma D option switchrate=10hz 43 44 /* 45 * Print header 46 */ 47 dtrace:::BEGIN 48 { 49 /* starting values */ 50 counts = $1 ? $1 : 10; 51 secs = $2 ? $2 : 5; 52 UDP_out = 0; 53 UDP_in = 0; 54 55 printf("Sampling... Please wait.\n"); 56 } 57 58 59 udp:::send 60 / args[1]->cs_pid != -1 / 61 { 62 @out[args[1]->cs_zoneid, args[1]->cs_pid, args[2]->ip_saddr, 63 args[4]->udp_sport, args[2]->ip_daddr, args[4]->udp_dport] = 64 sum(args[4]->udp_length); 65 } 66 67 udp:::receive 68 / args[1]->cs_pid != -1 / 69 { 70 @out[args[1]->cs_zoneid, args[1]->cs_pid, args[2]->ip_daddr, 71 args[4]->udp_dport, args[2]->ip_saddr, args[4]->udp_sport] = 72 sum(args[4]->udp_length); 73 } 74 75 /* 76 * UDP Systemwide Stats 77 */ 78 mib:::udpHCOutDatagrams { UDP_out += args[0]; } 79 mib:::udpHCInDatagrams { UDP_in += args[0]; } 80 81 profile:::tick-1sec 82 /secs != 0/ 83 { 84 secs--; 85 } 86 87 /* 88 * Print Report 89 */ 90 profile:::tick-1sec 91 /secs == 0/ 92 { 93 /* fetch 1 min load average */ 94 this->load1a = `hp_avenrun[0] / 65536; 95 this->load1b = ((`hp_avenrun[0] % 65536) * 100) / 65536; 96 97 /* print status */ 98 printf(%Y, load: %d.%02d, UDP datagrams in: %6d, ", 99 walltimestamp, this->load1a, this->load1b, UDP_in); 100 printf("UDP datagrams out: %6d\n\n", UDP_out); 101 102 /* print headers */ 103 printf("%6s %6s %-15s %5s %-15s %5s %9s\n", 104 "ZONE", "PID", "LADDR", "LPORT", "RADDR", "RPORT", "SIZE"); 105 106 /* print data */ 107 printa("%6d %6d %-15s %5d %-15s %5d %@9d\n", @out); 108 printf("\n"); 109 110 /* clear data */ 111 trunc(@out); 112 UDP_in = 0; 113 UDP_out = 0; 114 secs = 5; 115 counts--; 116 } 117 118 /* 119 * End of program 120 */ 121 profile:::tick-1sec 122 /counts == 0/ 123 { 124 exit(0); 125 } 126 127 /* 128 * Cleanup for Ctrl-C 129 */ 130 dtrace:::END 131 { 132 trunc(@out); 133 } 134