tcprst.d revision fab254e2b865295c3dd79c791650a3161d99e196
#!/usr/sbin/dtrace -Cqs
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma D option dynvarsize=64m
#define TH_RST 0x04
#define MAX_RECORDS 10
#define M_CTL 0x0d
#define PRINT_MAIN_HEADER() \
(printf("\n%-25s %-6s %-25s %-6s %-10s %-10s %8s %8s\n", \
"LADDR", "LPORT", "RADDR", "RPORT", "ISS", "IRS", \
"SND_CNT", "RCV_CNT"))
#define PRINT_RECORD_HEADER() \
(printf("%-20s %-20s %-3s %15s %15s %8s %8s %5s\n", \
"PROBENAME", "TIME", "S/R", "SEQ", "ACK", "DATALEN", \
"WND", "FLAGS"))
#define PRINT_MAIN_HEADER_VALUES() \
(printf("%-25s %-6d %-25s %-6d %-10d %-10d %8d %8d\n", \
laddr[self->conn_id], lport[self->conn_id], \
faddr[self->conn_id], fport[self->conn_id], \
iss[self->conn_id], irs[self->conn_id], \
send_count[self->conn_id], recv_count[self->conn_id]))
#define PRINT_HEADER() \
PRINT_MAIN_HEADER(); PRINT_MAIN_HEADER_VALUES(); \
PRINT_RECORD_HEADER()
#define PRINT_RECORD(i) \
(printf("%-20s %-20Y %-3s %15d %15d %8d %8d %2x\n", \
probe_name[self->conn_id, i], \
conn_time[self->conn_id, i], \
send_recv[self->conn_id, i], \
seqno[self->conn_id, i], \
ack[self->conn_id, i], \
datalen[self->conn_id, i], \
wnd[self->conn_id, i], \
flags[self->conn_id, i]))
tcp-trace-*
{
/* extract connection details */
this->mp = (mblk_t *)arg0;
this->mp = (this->mp->b_datap->db_type == M_CTL?
this->mp->b_cont : this->mp);
self->tcpp = (tcp_t *)arg1;
this->connp = (conn_t *)self->tcpp->tcp_connp;
self->iph = (ipha_t *)this->mp->b_rptr;
this->iph_length =
(int)(((ipha_t *)self->iph)->ipha_version_and_hdr_length
& 0xF) << 2;
self->tcph = (tcpha_t *)((char *)self->iph + this->iph_length);
this->tcph_length =
(((tcph_t *)self->tcph)->th_offset_and_rsrvd[0] >>2) &(0xF << 2);
/* ports */
self->i_lport = ntohs(this->connp->u_port.tcpu_ports.tcpu_lport);
self->i_fport = ntohs(this->connp->u_port.tcpu_ports.tcpu_fport);
/* IP addresses */
this->i_fad = (in6_addr_t *)&this->connp->connua_v6addr.connua_faddr;
this->i_lad = (in6_addr_t *)&this->connp->connua_v6addr.connua_laddr;
/* the address would either be IPv6 or IPv4-mapped-IPv6 */
self->i_faddr = inet_ntop(AF_INET6, (void *)this->i_fad);
self->i_laddr = inet_ntop(AF_INET6, (void *)this->i_lad);
/* create connection identifier, so we can track packets by conn */
self->conn_id = (uint64_t)self->tcpp->tcp_connp;
}
tcp-trace-*
/first[self->conn_id] == 0/
{
/* initialize counters - this is the first packet for this connection */
pcount[self->conn_id] = -1;
rollover[self->conn_id] = 0;
end_ptr[self->conn_id] = 0;
num[self->conn_id] = 0;
first[self->conn_id] = 1;
/* connection info */
laddr[self->conn_id] = self->i_laddr;
faddr[self->conn_id] = self->i_faddr;
lport[self->conn_id] = self->i_lport;
fport[self->conn_id] = self->i_fport;
iss[self->conn_id] = self->tcpp->tcp_iss;
irs[self->conn_id] = self->tcpp->tcp_irs;
}
tcp-trace-*
{
/* counters, to keep track of how much info to dump */
pcount[self->conn_id]++;
rollover[self->conn_id] |= pcount[self->conn_id]/MAX_RECORDS;
pcount[self->conn_id] = pcount[self->conn_id]%MAX_RECORDS;
self->pcount = pcount[self->conn_id];
end_ptr[self->conn_id] = self->pcount;
num[self->conn_id] = (rollover[self->conn_id]?
MAX_RECORDS : pcount[self->conn_id] + 1);
conn_time[self->conn_id, self->pcount] = walltimestamp;
/* tcp state info */
seqno[self->conn_id, self->pcount] = ntohl(self->tcph->tha_seq);
ack[self->conn_id, self->pcount] = ntohl(self->tcph->tha_ack);
datalen[self->conn_id, self->pcount] = ntohs(self->iph->ipha_length);
wnd[self->conn_id, self->pcount] = ntohs(self->tcph->tha_win);
probe_name[self->conn_id, self->pcount] = probename;
/* flag 0x04 indicates a RST packet */
flags[self->conn_id, self->pcount] = self->tcph->tha_flags;
self->flags = self->tcph->tha_flags;
}
tcp-trace-send
{
send_count[self->conn_id]++;
send_recv[self->conn_id, self->pcount] = "S";
}
tcp-trace-recv
{
recv_count[self->conn_id]++;
send_recv[self->conn_id, self->pcount] = "R";
}
tcp-trace-*
/(self->flags & TH_RST)/
{
PRINT_HEADER();
self->i = (end_ptr[self->conn_id] + MAX_RECORDS - num[self->conn_id]
+ 1)%MAX_RECORDS;
}
tcp-trace-*
/(self->flags & TH_RST) && (num[self->conn_id] >= 10)/
{
PRINT_RECORD(self->i);
self->i = (self->i + 1)%MAX_RECORDS;
num[self->conn_id]--;
}
tcp-trace-*
/(self->flags & TH_RST) && (num[self->conn_id] >= 9)/
{
PRINT_RECORD(self->i);
self->i = (self->i + 1)%MAX_RECORDS;
num[self->conn_id]--;
}
tcp-trace-*
/(self->flags & TH_RST) && (num[self->conn_id] >= 8)/
{
PRINT_RECORD(self->i);
self->i = (self->i + 1)%MAX_RECORDS;
num[self->conn_id]--;
}
tcp-trace-*
/(self->flags & TH_RST) && (num[self->conn_id] >= 7)/
{
PRINT_RECORD(self->i);
self->i = (self->i + 1)%MAX_RECORDS;
num[self->conn_id]--;
}
tcp-trace-*
/(self->flags & TH_RST) && (num[self->conn_id] >= 6)/
{
PRINT_RECORD(self->i);
self->i = (self->i + 1)%MAX_RECORDS;
num[self->conn_id]--;
}
tcp-trace-*
/(self->flags & TH_RST) && (num[self->conn_id] >= 5)/
{
PRINT_RECORD(self->i);
self->i = (self->i + 1)%MAX_RECORDS;
num[self->conn_id]--;
}
tcp-trace-*
/(self->flags & TH_RST) && (num[self->conn_id] >= 4)/
{
PRINT_RECORD(self->i);
self->i = (self->i + 1)%MAX_RECORDS;
num[self->conn_id]--;
}
tcp-trace-*
/(self->flags & TH_RST) && (num[self->conn_id] >= 3)/
{
PRINT_RECORD(self->i);
self->i = (self->i + 1)%MAX_RECORDS;
num[self->conn_id]--;
}
tcp-trace-*
/(self->flags & TH_RST) && (num[self->conn_id] >= 2)/
{
PRINT_RECORD(self->i);
self->i = (self->i + 1)%MAX_RECORDS;
num[self->conn_id]--;
}
tcp-trace-*
/(self->flags & TH_RST) && (num[self->conn_id] >= 1)/
{
PRINT_RECORD(self->i);
self->i = (self->i + 1)%MAX_RECORDS;
num[self->conn_id]--;
self->reset = self->conn_id;
}
tcp-trace-*
/self->reset/
{
pcount[self->reset] = -1;
rollover[self->reset] = 0;
end_ptr[self->reset] = 0;
num[self->reset] = 0;
self->reset = 0;
}
conn-destroy
{
/* clear old connection state */
this->conn_id = (uint64_t)arg0;
pcount[this->conn_id] = -1;
rollover[this->conn_id] = 0;
end_ptr[this->conn_id] = 0;
num[this->conn_id] = 0;
first[this->conn_id] = 0;
laddr[this->conn_id] = 0;
faddr[this->conn_id] = 0;
lport[this->conn_id] = 0;
fport[this->conn_id] = 0;
iss[this->conn_id] = 0;
irs[this->conn_id] = 0;
}