TCP header // RFC 9293

A 20-byte header, eight control bits and a deceptively small option space. Toggle the flags, inspect the TLV kinds, and let the encoder compute the pseudo-header checksum that makes a segment believable.

RFC 9293 · TCP RFC 7323 · WS/TS RFC 2018 · SACK RFC 3168 · ECN 20–60 bytes pseudo-header
layer transport header 20 B + 0–40 B options checksum IPv4 pseudo-header byte order big-endian

01Header layout

click a field to pin it · esc clears

Sequence Number and Acknowledgment Number are 32-bit unsigned counters that wrap. Data Offset counts 32-bit words, so 5 means the 20-byte minimum; options occupy the rest up to 40 bytes. The four reserved bits must be zero.

byte 12 (the 13th byte) is where diagrams disagree

Data Offset (4 bits), Reserved (4 bits), then the flag octet: CWR, ECE, URG, ACK, PSH, RST, SYN, FIN. Some older diagrams split the reserved nibble into a 3-bit reserved field plus the experimental NS bit (RFC 3540). RFC 8311 deprecated NS; treat it as reserved.

02Flag explorer

bits 104–111 · byte 13

Flip the bits to see the raw octet, the tcpdump-style notation and the names. The recipes below set common legitimate and scan combinations; they are here to explain the wire, not to defeat a specific IDS.

TCP control flagsRFC 9293 · RFC 3168
octet 0x02 tcpdump [S] names SYN bit 110 = 0x02

CWR and ECE are ECN signals (RFC 3168). URG makes the Urgent Pointer meaningful. ACK makes Acknowledgment Number meaningful; PSH asks the receiver to deliver buffered data; RST aborts; SYN synchronizes; FIN ends the sender's byte stream.

03Options & TLVs

kind 8-bit · length includes both

Most TCP options are TLVs. Kind 0 (EOL) and 1 (NOP) are one byte and have no length. All others have a one-byte length covering kind, length and value. The whole option list is padded to a 4-byte boundary and counted by Data Offset.

TCP option TLV
8 + 8 + n bits
Kind1 byte
Length1 byte · 2–255
data
length − 2 bytes · padded with EOL / NOP to a 4-byte boundary

EOL (0x00) and NOP (0x01) are single bytes, not TLVs. A length below 2 is malformed. The option list is limited to 40 bytes by the 4-bit Data Offset.

KindNameLength (B)ReferenceNotes
0EOL1RFC 9293 §3.1End of option list; the rest should be padding.
1NOP1RFC 9293 §3.1Alignment filler; no length byte.
2MSS4RFC 9293 §3.116-bit maximum segment size; normally only in SYN.
3WS · Window Scale3RFC 7323 §2.2One shift byte; max useful value 14.
4SACK-permitted2RFC 2018 §2No data; negotiated in SYN.
5SACK2 + 8nRFC 2018 §3n ≤ 4 blocks of 32-bit left/right edges.
8Timestamps10RFC 7323 §3.2TSval and TSecr, both 32-bit.
19MD518RFC 238516-byte digest; historic, superseded by TCP-AO.
28UTO · User Timeout4RFC 5482 §316-bit timeout + 16-bit granularity.
29TCP-AO≥ 4RFC 5925 §3.1KeyID, RNextKeyID and MAC; variable.
30MPTCPvarRFC 8684 §3Multipath signaling; subtypes in the first data nibble.
34TFO · Fast Open6–18RFC 7413 §4.1Cookie in SYN; 4–16 bytes. An empty request may be encoded as length 2.
253/254ExperimentalvarRFC 6994Reserved for experiments; do not rely on them.

04Encoder

pseudo-header checksum when IPs are supplied

Build a TCP segment with a correct header checksum. Supply IPv4 source and destination addresses to compute the pseudo-header checksum; leave them blank to emit checksum 0x0000. Payload is optional and is appended after the header.

build a TCP segment

20–60 B header

The checksum covers a 12-byte pseudo-header (source, destination, zero, protocol 6, TCP length) followed by the TCP header and payload. A valid checksum is not a valid connection.

wire output

waiting
Set the fields and press Build segment.
segment hex · header + payload
no bytes built yet
pseudo-header, not a real header

The 12 bytes of source address, destination address, zero, protocol and TCP length are never transmitted. Both ends reconstruct them from the IP layer. For IPv6 the pseudo-header is 40 bytes and uses the next-header value instead of protocol.

05Decoder

raw TCP segment or full IPv4 packet

Paste a TCP segment. If the input starts with a plausible IPv4 header whose protocol is 6, the decoder extracts the TCP segment, uses the IPv4 addresses for checksum verification and reports the enclosing packet. Raw segments are decoded but their checksum is marked unverified because the pseudo-header is missing.

parse bytes

RFC 9293 · options · flags
No input decoded yet.

06Wire notes

where TCP implementations hurt
the checksum is over a fake header

Copying a TCP segment without its IP addresses makes the checksum unverifiable. This is why packet generators ask for the pseudo-header tuple. It is also why NAT devices must recompute the TCP/UDP checksum when they rewrite addresses.

  • Data Offset is words. 5 = 20 bytes, 15 = 60 bytes. A value below 5 is malformed; a value larger than the segment means the options are truncated.
  • Options are negotiated, not universal. Window Scale and SACK-permitted are normally SYN-only; timestamps are negotiated in both directions; SACK blocks appear after loss.
  • Window Scale shifts the 16-bit window. The shift is 0–14; values above 14 should be treated as 14. The scale applies to later segments, not the SYN itself.
  • MSS is not the path MTU. It is the largest TCP payload the sender can receive, normally MTU − 40. MSS 0 is invalid.
  • The urgent pointer is practically dead. URG is rarely used and interpreted inconsistently; do not design new protocols around it.
  • NS is historic. RFC 3540 defined the ECN nonce bit; RFC 8311 deprecated the nonce. Modern parsers treat the bit as reserved.
  • Flags are not authentication. Anyone can forge a RST or a SYN. TCP sequence numbers and cookies provide some resistance, not identity.

References

next protocol QUIC frames & varints ->