tcpstate.d Reports TCP State Changes
This DTrace script demonstrates the capability to trace TCP state changes:
#!/usr/sbin/dtrace -s
#pragma D option quiet
#pragma D option switchrate=10
int last[int];
dtrace:::BEGIN
{
printf(" %3s %12s %-20s %-20s\n", "CPU", "DELTA(us)", "OLD", "NEW");
}
tcp:::state-change
/ last[args[1]->cs_cid] /
{
this->elapsed = (timestamp - last[args[1]->cs_cid]) / 1000;
printf(" %3d %12d %-20s -> %-20s\n", cpu, this->elapsed,
tcp_state_string[args[5]->tcps_state],
tcp_state_string[args[3]->tcps_state]);
last[args[1]->cs_cid] = timestamp;
}
tcp:::state-change
/ last[args[1]->cs_cid] == 0 /
{
printf(" %3d %12s %-20s -> %-20s\n", cpu, "-",
tcp_state_string[args[5]->tcps_state],
tcp_state_string[args[3]->tcps_state]);
last[args[1]->cs_cid] = timestamp;Run this script on a system for couple of minutes:
# ./tcpstate.d
CPU DELTA(us) OLD NEW
0 - state-listen -> state-syn-received
0 613 state-syn-received -> state-established
0 - state-idle -> state-bound
0 63 state-bound -> state-syn-sent
0 685 state-syn-sent -> state-bound
0 22 state-bound -> state-idle
0 114 state-idle -> state-closed In the preceding output, an inbound connection is traced, It takes 613 us to go from syn-received to established. An outbound connection attempt is also made to a closed port. It takes 63 us to go from bound to syn-sent, 685 us to go from syn-sent to bound.
The following table describes the output fields.
| Field | Description |
|---|---|
|
|
CPU id for the event |
|
|
time since previous event for that connection, microseconds |
|
|
old TCP state |
|
|
new TCP state |