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.
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.
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 13Flip 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.
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.
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.
| Kind | Name | Length (B) | Reference | Notes |
|---|---|---|---|---|
0 | EOL | 1 | RFC 9293 §3.1 | End of option list; the rest should be padding. |
1 | NOP | 1 | RFC 9293 §3.1 | Alignment filler; no length byte. |
2 | MSS | 4 | RFC 9293 §3.1 | 16-bit maximum segment size; normally only in SYN. |
3 | WS · Window Scale | 3 | RFC 7323 §2.2 | One shift byte; max useful value 14. |
4 | SACK-permitted | 2 | RFC 2018 §2 | No data; negotiated in SYN. |
5 | SACK | 2 + 8n | RFC 2018 §3 | n ≤ 4 blocks of 32-bit left/right edges. |
8 | Timestamps | 10 | RFC 7323 §3.2 | TSval and TSecr, both 32-bit. |
19 | MD5 | 18 | RFC 2385 | 16-byte digest; historic, superseded by TCP-AO. |
28 | UTO · User Timeout | 4 | RFC 5482 §3 | 16-bit timeout + 16-bit granularity. |
29 | TCP-AO | ≥ 4 | RFC 5925 §3.1 | KeyID, RNextKeyID and MAC; variable. |
30 | MPTCP | var | RFC 8684 §3 | Multipath signaling; subtypes in the first data nibble. |
34 | TFO · Fast Open | 6–18 | RFC 7413 §4.1 | Cookie in SYN; 4–16 bytes. An empty request may be encoded as length 2. |
253/254 | Experimental | var | RFC 6994 | Reserved 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 headerwire output
waitingno bytes built yet
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 packetPaste 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 · flags06Wire notes
where TCP implementations hurtCopying 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.