tcpio.d
Reports TCP Packet Details
The following DTrace script traces TCP packets and prints various details:
#!/usr/sbin/dtrace -s #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf(" %3s %15s:%-5s %15s:%-5s %6s %s\n", "CPU", "LADDR", "LPORT", "RADDR", "RPORT", "BYTES", "FLAGS"); } tcp:::send { this->length = args[2]->ip_plength - args[4]->tcp_offset; printf(" %3d %16s:%-5d -> %16s:%-5d %6d (", cpu, args[2]->ip_saddr, args[4]->tcp_sport, args[2]->ip_daddr, args[4]->tcp_dport, this->length); } tcp:::receive { this->length = args[2]->ip_plength - args[4]->tcp_offset; printf(" %3d %16s:%-5d <- %16s:%-5d %6d (", cpu, args[2]->ip_daddr, args[4]->tcp_dport, args[2]->ip_saddr, args[4]->tcp_sport, this->length); } tcp:::send, tcp:::receive { printf("%s", args[4]->tcp_flags & TH_FIN ? "FIN|" : ""); printf("%s", args[4]->tcp_flags & TH_SYN ? "SYN|" : ""); printf("%s", args[4]->tcp_flags & TH_RST ? "RST|" : ""); printf("%s", args[4]->tcp_flags & TH_PUSH ? "PUSH|" : ""); printf("%s", args[4]->tcp_flags & TH_ACK ? "ACK|" : ""); printf("%s", args[4]->tcp_flags & TH_URG ? "URG|" : ""); printf("%s", args[4]->tcp_flags & TH_ECE ? "ECE|" : ""); printf("%s", args[4]->tcp_flags & TH_CWR ? "CWR|" : ""); printf("%s", args[4]->tcp_flags == 0 ? "null " : ""); printf("\b)\n"); }
This example output has captured a TCP handshake:
# ./tcpio.d
CPU LADDR:LPORT RADDR:RPORT BYTES FLAGS
1 192.0.2.8/27:22 -> 192.0.2.40/27:60337 464 (PUSH|ACK)
1 192.0.2.8/27:22 -> 192.0.2.40/27:60337 48 (PUSH|ACK)
2 192.0.2.8/27:22 -> 192.0.2.40/27:60337 20 (PUSH|ACK)
3 192.0.2.8/27:22 <- 192.0.2.40/27:60337 0 (SYN)
3 192.0.2.8/27:22 -> 192.0.2.40/27:60337 0 (SYN|ACK)
3 192.0.2.8/27:22 <- 192.0.2.40/27:60337 0 (ACK)
3 192.0.2.8/27:22 <- 192.0.2.40/27:60337 0 (ACK)
3 192.0.2.8/27:22 <- 192.0.2.40/27:60337 20 (PUSH|ACK)
3 192.0.2.8/27:22 -> 192.0.2.40/27:60337 0 (ACK)
3 192.0.2.8/27:22 <- 192.0.2.40/27:60337 0 (ACK)
3 192.0.2.8/27:22 <- 192.0.2.40/27:60337 376 (PUSH|ACK)
3 192.0.2.8/27:22 -> 192.0.2.40/27:60337 0 (ACK)
3 192.0.2.8/27:22 <- 192.0.2.40/27:60337 24 (PUSH|ACK)
2 192.0.2.8/27:22 -> 192.0.2.40/27:60337 736 (PUSH|ACK)
3 192.0.2.8/27:22 <- 192.0.2.40/27:60337 0 (ACK)
The following table describes the output fields.
Field | Description |
---|---|
|
CPU id that event occurred on |
|
Local IP address |
|
Local TCP port |
|
Remote IP address |
|
Remote TCP port |
|
TCP payload bytes |
|
TCP flags |
Note:
The output may be shuffled slightly on multi-CPU servers due to DTrace per-CPU buffering, and events such as the TCP handshake can be printed out of order. Keep an eye on changes in the CPU column, or add a timestamp column to this script and post sort.