TCP Flags & States Reference

TCP flags and states cheatsheet — SYN, ACK, FIN, RST, PSH, URG. TCP 3-way handshake, connection states TIME_WAIT, CLOSE_WAIT, ESTABLISHED. Debug network issues at the TCP level.

6 min read

This document serves as a reference for TCP flags and states, crucial for understanding and debugging network communication.

What it is

A reference for the six TCP flags (SYN, FIN, ACK, RST, PSH, URG) and the common states a TCP connection transitions through during its lifecycle.

Installation

No installation required. This is a conceptual reference.

Core Concepts

TCP (Transmission Control Protocol) is a connection-oriented protocol that provides reliable, ordered, and error-checked delivery of a stream of bytes between applications running on hosts communicating via an IP network. The flags and states dictate how this connection is established, maintained, and terminated.

TCP Flags

These are single-bit fields in the TCP header that control the behavior of the connection.

  • SYN (Synchronize): Used to initiate a connection.
  • FIN (Finish): Used to signal the end of data transmission from the sender.
  • ACK (Acknowledge): Used to acknowledge received data.
  • RST (Reset): Used to abort a connection.
  • PSH (Push): Tells the receiving TCP to immediately deliver the data to the application.
  • URG (Urgent): Indicates that the Urgent Pointer field is being used to point to urgent data.

TCP States

These represent the different phases a TCP connection goes through.

  • CLOSED: The initial state, no connection exists.
  • LISTEN: The server is waiting for an incoming connection.
  • SYN-SENT: The client has sent a SYN packet and is waiting for a SYN-ACK from the server.
  • SYN-RECEIVED: The server has received a SYN and sent a SYN-ACK, waiting for the final ACK.
  • ESTABLISHED: The connection is active and data can be exchanged.
  • FIN-WAIT-1: The client has sent a FIN and is waiting for an ACK or a FIN from the server.
  • FIN-WAIT-2: The client has received an ACK for its FIN and is waiting for a FIN from the server.
  • CLOSE-WAIT: The server has received a FIN and sent an ACK, waiting for the application to close the connection.
  • CLOSING: Both sides have sent a FIN and are waiting for the other side’s FIN.
  • LAST-ACK: The server has sent its FIN and is waiting for the final ACK from the client.
  • TIME-WAIT: The client has sent its final ACK and is waiting for a timeout to ensure the ACK was received.

Commands / Usage

This section describes how TCP flags and states are observed, typically using network analysis tools like tcpdump or Wireshark. The examples show how to filter and interpret traffic based on flags and states.

Observing TCP Flags with tcpdump

  • Capture all TCP packets:

    tcpdump -i eth0 'tcp'
    

    Explanation: Captures all packets on interface eth0 that are using the TCP protocol.

  • Capture packets with the SYN flag set:

    tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0'
    

    Explanation: Captures TCP packets where the SYN flag is set. tcp[tcpflags] accesses the TCP flags byte, and & tcp-syn masks it to check for the SYN bit.

  • Capture packets with the FIN flag set:

    tcpdump -i eth0 'tcp[tcpflags] & tcp-fin != 0'
    

    Explanation: Captures TCP packets where the FIN flag is set.

  • Capture packets with the ACK flag set:

    tcpdump -i eth0 'tcp[tcpflags] & tcp-ack != 0'
    

    Explanation: Captures TCP packets where the ACK flag is set.

  • Capture packets with the RST flag set:

    tcpdump -i eth0 'tcp[tcpflags] & tcp-rst != 0'
    

    Explanation: Captures TCP packets where the RST flag is set.

  • Capture packets with the PSH flag set:

    tcpdump -i eth0 'tcp[tcpflags] & tcp-psh != 0'
    

    Explanation: Captures TCP packets where the PSH flag is set.

  • Capture packets with the URG flag set:

    tcpdump -i eth0 'tcp[tcpflags] & tcp-urg != 0'
    

    Explanation: Captures TCP packets where the URG flag is set.

  • Capture packets with SYN and ACK flags set (SYN-ACK):

    tcpdump -i eth0 'tcp[tcpflags] & (tcp-syn|tcp-ack) == (tcp-syn|tcp-ack)'
    

    Explanation: Captures TCP packets where both SYN and ACK flags are set. This is part of the 3-way handshake.

  • Capture packets with FIN and ACK flags set (FIN-ACK):

    tcpdump -i eth0 'tcp[tcpflags] & (tcp-fin|tcp-ack) == (tcp-fin|tcp-ack)'
    

    Explanation: Captures TCP packets where both FIN and ACK flags are set. This is part of the connection termination.

  • Capture packets with RST and ACK flags set (RST-ACK):

    tcpdump -i eth0 'tcp[tcpflags] & (tcp-rst|tcp-ack) == (tcp-rst|tcp-ack)'
    

    Explanation: Captures TCP packets where both RST and ACK flags are set. Indicates a connection reset.

Observing TCP States with tcpdump (Indirectly)

While tcpdump directly shows flags, inferring states requires observing sequences of packets. Wireshark provides a more direct view of states.

  • Observe the 3-way handshake (SYN, SYN-ACK, ACK):

    tcpdump -i eth0 'tcp port 80' -v
    

    Explanation: Captures TCP traffic on port 80 and shows verbose output, including flags, which helps identify the handshake sequence. Look for [S], [S.], [.] in the output.

  • Observe connection termination (FIN-ACK, ACK, FIN, ACK):

    tcpdump -i eth0 'tcp port 80' -v
    

    Explanation: Observe the sequence of FIN and ACK flags indicating graceful connection closure. Look for [F], [.], [F], [.].

  • Observe connection reset (RST):

    tcpdump -i eth0 'tcp port 80 and tcp[tcpflags] & tcp-rst != 0'
    

    Explanation: Captures packets that forcibly terminate a connection.

Common Patterns

  • Identifying the start of a connection attempt:

    tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack == 0'
    

    Explanation: Shows packets that are initiating a connection (SYN flag set, ACK flag not set).

  • Identifying the response to a connection attempt:

    tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack != 0'
    

    Explanation: Shows packets that are acknowledging a connection attempt and also synchronizing (SYN-ACK flag set).

  • Identifying the final acknowledgment of a connection:

    tcpdump -i eth0 'tcp[tcpflags] & tcp-syn == 0 and tcp[tcpflags] & tcp-ack != 0'
    

    Explanation: Shows packets that are purely acknowledging data or the final ACK of the handshake (ACK flag set, SYN flag not set).

  • Capturing only data packets (PSH and ACK set):

    tcpdump -i eth0 'tcp[tcpflags] & (tcp-psh|tcp-ack) == (tcp-psh|tcp-ack)'
    

    Explanation: Captures packets that are likely carrying application data, as both PSH and ACK flags are set.

  • Filtering out ACK packets to see control traffic:

    tcpdump -i eth0 'tcp and not tcp[tcpflags] & tcp-ack != 0'
    

    Explanation: Shows all TCP traffic except for those packets that are solely acknowledgments.

Gotchas

  • Flag Interpretation: The tcp[tcpflags] byte contains all six flags. When filtering, it’s important to use bitwise operations (&) and comparisons (!= 0, == 0, == mask) correctly. For example, checking for only SYN requires tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & (tcp-fin|tcp-rst|tcp-psh|tcp-urg|tcp-ack) == 0.
  • State Inference: tcpdump shows individual packets. Determining the current state of a connection requires observing the sequence of flags across multiple packets. Tools like Wireshark have built-in state tracking for easier visualization.
  • tcp-ack Filter: The tcp-ack flag is often set along with other flags (e.g., SYN-ACK, FIN-ACK). Simply filtering for tcp-ack != 0 will capture a vast majority of TCP traffic.
  • tcp-ack == 0: This filter is useful for identifying packets that are not acknowledgments, such as initial SYNs or FINs.
  • Port Numbers: When debugging specific application connections, always include relevant port numbers in your tcpdump filters (e.g., tcp port 80, tcp port 443, tcp port 22).
  • Interface: Ensure you are capturing on the correct network interface (-i <interface>).
  • Root Privileges: tcpdump typically requires root privileges to capture raw network traffic.