1#!/usr/sbin/dtrace -s 2/* 3 * Copyright (c) 2015 George V. Neville-Neil 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * The tcpdebug D script uses the tcp:kernel::debug tracepoints 28 * to replicate the action of turning on TCPDEBUG in a kernel configuration. 29 * 30 * A TCP debug statement shows a connection's 31 * 32 * direction: input, output, user, drop 33 * state: CLOSED, LISTEN, SYN_SENT, SYN_RCVD, ESTABLISHED, 34 * CLOSE_WAIT, FIN_WAIT_1, CLOSING, LAST_ACK, FIN_WAIT_2,TIME_WAIT 35 * sequence: sequence space 36 * 37 * congestion: rcv_nxt, rcv_wnd, rcv_up, snd_una, snd_nxt, snx_max, 38 * snd_wl1, snd_wl2, snd_wnd 39 * 40 * NOTE: Only sockets with SO_DEBUG set will be shown. 41 * 42 * Usage: tcpdebug 43 */ 44 45#pragma D option quiet 46tcp:kernel::debug-input 47/args[0]->tcps_debug/ 48{ 49 seq = args[1]->tcp_seq; 50 ack = args[1]->tcp_ack; 51 len = args[2]->ip_plength - sizeof(struct tcphdr); 52 flags = args[1]->tcp_flags; 53 54 printf("%p %s: input [%xu..%xu]", arg0, 55 tcp_state_string[args[0]->tcps_state], seq, seq + len); 56 57 printf("@%x, urp=%x", ack, args[1]->tcp_urgent); 58 59 printf("%s", flags != 0 ? "<" : ""); 60 printf("%s", flags & TH_SYN ? "SYN," :""); 61 printf("%s", flags & TH_ACK ? "ACK," :""); 62 printf("%s", flags & TH_FIN ? "FIN," :""); 63 printf("%s", flags & TH_RST ? "RST," :""); 64 printf("%s", flags & TH_PUSH ? "PUSH," :""); 65 printf("%s", flags & TH_URG ? "URG," :""); 66 printf("%s", flags & TH_ECE ? "ECE," :""); 67 printf("%s", flags & TH_CWR ? "CWR," :""); 68 printf("%s", flags & TH_AE ? "AE" :""); 69 printf("%s", flags != 0 ? ">" : ""); 70 71 printf("\n"); 72 printf("\trcv_(nxt,wnd,up) (%x,%x,%x) snd_(una,nxt,max) (%x,%x,%x)\n", 73 args[0]->tcps_rnxt, args[0]->tcps_rwnd, args[0]->tcps_rup, 74 args[0]->tcps_suna, args[0]->tcps_snxt, args[0]->tcps_smax); 75 printf("\tsnd_(wl1,wl2,wnd) (%x,%x,%x)\n", 76 args[0]->tcps_swl1, args[0]->tcps_swl2, args[0]->tcps_swnd); 77 78} 79 80tcp:kernel::debug-output 81/args[0]->tcps_debug/ 82{ 83 seq = args[1]->tcp_seq; 84 ack = args[1]->tcp_ack; 85 len = args[2]->ip_plength - sizeof(struct tcphdr); 86 flags = args[1]->tcp_flags; 87 88 printf("%p %s: output [%x..%x]", arg0, 89 tcp_state_string[args[0]->tcps_state], seq, seq + len); 90 91 printf("@%x, urp=%x", ack, args[1]->tcp_urgent); 92 93 printf("%s", flags != 0 ? "<" : ""); 94 printf("%s", flags & TH_SYN ? "SYN," :""); 95 printf("%s", flags & TH_ACK ? "ACK," :""); 96 printf("%s", flags & TH_FIN ? "FIN," :""); 97 printf("%s", flags & TH_RST ? "RST," :""); 98 printf("%s", flags & TH_PUSH ? "PUSH," :""); 99 printf("%s", flags & TH_URG ? "URG," :""); 100 printf("%s", flags & TH_ECE ? "ECE," :""); 101 printf("%s", flags & TH_CWR ? "CWR," :""); 102 printf("%s", flags & TH_AE ? "AE" :""); 103 printf("%s", flags != 0 ? ">" : ""); 104 105 printf("\n"); 106 printf("\trcv_(nxt,wnd,up) (%u,%x,%x) snd_(una,nxt,max) (%x,%x,%x)\n", 107 args[0]->tcps_rnxt, args[0]->tcps_rwnd, args[0]->tcps_rup, 108 args[0]->tcps_suna, args[0]->tcps_snxt, args[0]->tcps_smax); 109 printf("\tsnd_(wl1,wl2,wnd) (%x,%x,%x)\n", 110 args[0]->tcps_swl1, args[0]->tcps_swl2, args[0]->tcps_swnd); 111 112} 113 114tcp:kernel::debug-drop 115/args[0]->tcps_debug/ 116{ 117 printf("%p %s: output [x..x] @%x, urp=%x\n", arg0, 118 tcp_state_string[args[0]->tcps_state], 119 args[1]->tcp_ack, 120 args[1]->tcp_urgent); 121 122 seq = args[1]->tcp_seq; 123 ack = args[1]->tcp_ack; 124 len = args[2]->ip_plength - sizeof(struct tcphdr); 125 flags = args[1]->tcp_flags; 126 127 printf("%p %s: drop [%x..%x]", arg0, 128 tcp_state_string[args[0]->tcps_state], seq, seq + len); 129 130 printf("@%x, urp=%x", ack, args[1]->tcp_urgent); 131 132 printf("%s", flags != 0 ? "<" : ""); 133 printf("%s", flags & TH_SYN ? "SYN," :""); 134 printf("%s", flags & TH_ACK ? "ACK," :""); 135 printf("%s", flags & TH_FIN ? "FIN," :""); 136 printf("%s", flags & TH_RST ? "RST," :""); 137 printf("%s", flags & TH_PUSH ? "PUSH," :""); 138 printf("%s", flags & TH_URG ? "URG," :""); 139 printf("%s", flags & TH_ECE ? "ECE," :""); 140 printf("%s", flags & TH_CWR ? "CWR," :""); 141 printf("%s", flags & TH_AE ? "AE" :""); 142 printf("%s", flags != 0 ? ">" : ""); 143 144 printf("\n"); 145 printf("\trcv_(nxt,wnd,up) (%x,%x,%x) snd_(una,nxt,max) (%x,%x,%x)\n", 146 args[0]->tcps_rnxt, args[0]->tcps_rwnd, args[0]->tcps_rup, 147 args[0]->tcps_suna, args[0]->tcps_snxt, args[0]->tcps_smax); 148 printf("\tsnd_(wl1,wl2,wnd) (%x,%x,%x)\n", 149 args[0]->tcps_swl1, args[0]->tcps_swl2, args[0]->tcps_swnd); 150 151} 152 153tcp:kernel::debug-user 154/args[0]->tcps_debug/ 155{ 156 printf("%p %s: user ", arg0, 157 tcp_state_string[args[0]->tcps_state]); 158 159 printf("%s", prureq_string[arg1]); 160 printf("\n"); 161 printf("\trcv_(nxt,wnd,up) (%x,%x,%x) snd_(una,nxt,max) (%x,%x,%x)\n", 162 args[0]->tcps_rnxt, args[0]->tcps_rwnd, args[0]->tcps_rup, 163 args[0]->tcps_suna, args[0]->tcps_snxt, args[0]->tcps_smax); 164 printf("\tsnd_(wl1,wl2,wnd) (%x,%x,%x)\n", 165 args[0]->tcps_swl1, args[0]->tcps_swl2, args[0]->tcps_swnd); 166 167} 168 169