🪟 Windows TippsKB5129194 Windows 11 26H1 Out of Band Update - Deskmodder.de(14.09.2026 um 19:25 Uhr)
🪟 Windows TippsGoogle Gemini: Neue Windows-App holt die KI aus dem Browser(14.09.2026 um 06:00 Uhr)
🪟 Windows TippsKB5129194 Windows 11 26H1 Out of Band Update - Deskmodder.de(14.09.2026 um 19:25 Uhr)
🪟 Windows TippsGoogle Gemini: Neue Windows-App holt die KI aus dem Browser(14.09.2026 um 06:00 Uhr)

🔧 Programmierung 🕛 vor 2 Monaten 10 Min Lesezeit
0

One TCP Connection, From SYN to FIN: Capture the Whole Lifecycle in tcpdump

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

Originally published at series.




This post is part of Protocol Lab, a free, hands-on series for learning networking protocols by building and breaking them in a container lab. All the lab material — topologies, configs, and scripts — lives in the repo:




Expected time: 50–65 minutes.






The Goal



By the end, you should be able to label each packet in this sketch:




CODE
client                          server
| ---- SYN seq=x -----------> | connection requested
| <--- SYN,ACK seq=y ack=x+1 - | accepted, server ISN
| ---- ACK ack=y+1 ---------> | handshake complete (ESTABLISHED)
| ==== data / echo =========> | one small exchange
| ---- FIN -----------------> | client done sending
| <--- ACK ------------------ |
| <--- FIN ------------------ | server done sending
| ---- ACK -----------------> | both sides closed









What You Will Learn




  • Why opening a TCP connection takes three packets, not one.

  • What SYN, ACK, FIN, and RST flags mean in a capture.

  • How the initial sequence number (ISN) and ack = seq + 1 tie the handshake together.

  • Why closing is a four-way exchange (each direction closes independently).

  • How to read tcpdump flag notation: [S], [S.], [.], [P.], [F.], [R].



This lab does not cover:




  • Retransmission, windowing, and loss recovery (that is Lab 08).

  • Congestion control algorithms.

  • TLS or any application-layer protocol on top of TCP.

  • TCP options in depth (MSS, window scaling, SACK, timestamps).






Where to Read in the RFCs



The required reading this time is below. RFC 9293 is the current TCP specification, replacing RFC 793.











































RFC Section What to focus on
RFC 9293 3.1 Header format and control bits (SYN/ACK/FIN/RST)
RFC 9293 3.4 Sequence numbers, the ISN, and the ack = seq + 1 idea
RFC 9293 3.5 Connection establishment (the 3-way handshake)
RFC 9293 3.6 Connection termination (the FIN-based 4-way close)
RFC 9293 3.3.2 State transitions (LISTEN / SYN-SENT / ESTABLISHED / FIN-WAIT / TIME-WAIT)
RFC 5737 3 Confirming the addresses used in this lab are documentation-only





The Big Picture



The topology couldn't be simpler: two nodes joined by a single link. The client connects once to a TCP port on the server.




CODE
client (10.0.0.1) ------ eth1/eth1 ------ server (10.0.0.2:8080)






The server runs an echo listener (it returns whatever bytes it receives). The client sends one line, receives the echo, and closes the connection. The whole time, tcpdump runs on the client side so the handshake through the teardown lands in a single pcap.




CODE
sequenceDiagram
participant C as client 10.0.0.1
participant S as server 10.0.0.2:8080

Note over C,S: 3-way handshake
C->>S: SYN seq=x
S->>C: SYN,ACK seq=y ack=x+1
C->>S: ACK ack=y+1
Note over C,S: ESTABLISHED

C->>S: PSH,ACK "hello-tcp\n"
S->>C: ACK
S->>C: PSH,ACK "hello-tcp\n" (echo)
C->>S: ACK

Note over C,S: 4-way teardown
C->>S: FIN,ACK
S->>C: ACK
S->>C: FIN,ACK
C->>S: ACK






Both nodes use nicolaka/netshoot. It ships ip, tcpdump, nc (OpenBSD netcat), and socat, so no additional images are needed. The echo server is built with socat instead of ncat (the nmap variant with --exec), which netshoot no longer includes.




Note: The addresses used here are local, documentation-style space (RFC 5737), so nothing in this lab touches the real internet.







What You Need



Recommended environment:




  • Linux / WSL2 / a Linux VM

  • Docker

  • containerlab

  • tcpdump (on the host; the netshoot containers bundle it too)



Images used:




  • nicolaka/netshoot:latest






Running the Lab



These steps run inside the Linux environment where containerlab is installed.



If you have the repo checked out, the quick path runs the whole verification for you:




CODE
./scripts/labctl.sh run tcp-07






labctl.sh run tcp-07 deploys the topology, starts the echo listener, collects the tcpdump capture, runs one connection, verifies the handshake and teardown, and destroys the lab.



Or step through it manually:






1. Move into the working directory






CODE
cd protocol-lab/examples/tcp-07









2. Deploy






CODE
sudo containerlab deploy -t tcp-07.clab.yml
docker ps --format "table {{.Names}}\t{{.Status}}"






Confirm that clab-tcp-07-client and clab-tcp-07-server are up.






3. Start the echo listener on the server



Start a tiny TCP server in the background that returns whatever bytes it receives.




CODE
docker exec -d clab-tcp-07-server socat TCP-LISTEN:8080,reuseaddr,fork EXEC:/bin/cat









4. Arm the capture on the client



In a separate shell, run tcpdump on the client-side link (foreground is fine if you're watching live).




CODE
docker exec -it clab-tcp-07-client tcpdump -i eth1 -n "tcp port 8080"






The -n flag disables name resolution, so addresses and flags read exactly as they are.






5. Connect exactly once



In yet another shell, send one line from the client, receive the echo, and close.




CODE
docker exec -it clab-tcp-07-client sh -c "printf 'hello-tcp\n' | nc -w2 10.0.0.2 8080"






If hello-tcp comes back as the echo, the connection was established, data made a round trip, and the connection closed.






6. Read the capture



The tcpdump side shows a sequence like this (the values change every run):




CODE
10.0.0.1.44002 > 10.0.0.2.8080: Flags [S],  seq 1000000000, ...          <- SYN
10.0.0.2.8080 > 10.0.0.1.44002: Flags [S.], seq 2000000000, ack 1000000001 <- SYN-ACK
10.0.0.1.44002 > 10.0.0.2.8080: Flags [.], ack 1 <- ACK (handshake complete)
10.0.0.1.44002 > 10.0.0.2.8080: Flags [P.], seq 1:11, ack 1, length 10 <- data "hello-tcp\n"
10.0.0.2.8080 > 10.0.0.1.44002: Flags [P.], seq 1:11, ack 11, length 10 <- echo
10.0.0.1.44002 > 10.0.0.2.8080: Flags [F.], seq 11, ack 11 <- FIN (client done sending)
10.0.0.2.8080 > 10.0.0.1.44002: Flags [F.], seq 11, ack 12 <- FIN (server done sending)
10.0.0.1.44002 > 10.0.0.2.8080: Flags [.], ack 12 <- final ACK






tcpdump flag notation:




































Notation Meaning
[S] SYN
[S.] SYN + ACK
[.] ACK only
[P.] PSH + ACK (carries data)
[F.] FIN + ACK
[R] RST





Expected Output



Rather than an exact byte-for-byte match, what matters is that you can find:




  • One [S] (SYN) and one [S.] (SYN-ACK) at the start.

  • The SYN-ACK's ack equal to the SYN's seq + 1.

  • Data lines (length > 0) in both directions.


  • [F.] (FIN) from both sides, closed out by a final [.] (ACK).






Why It Works



TCP builds a reliable byte stream on top of unreliable IP. To do that, both ends agree on where the other side starts counting (the ISN) before any data is sent.





  • Why three packets? The client's SYN declares "I will send starting from seq=x." The server ACKs it (ack=x+1) while returning its own SYN (seq=y). The client then ACKs the server's SYN (ack=y+1), and the initial sequence numbers are pinned down in both directions. One round trip can only synchronize one direction, so at least three packets are needed.


  • Why ack = seq + 1? A SYN consumes one sequence number (even though it carries no data). So the peer replies with seq + 1 as the next number it expects. A FIN consumes one as well.


  • Why does closing take four packets? Each direction of a TCP connection closes independently (half-close). When the client sends its FIN, the server may still have data to send. So each direction closes on its own: "client's FIN → server's ACK," then "server's FIN → client's ACK." Because this lab's echo server closes immediately, the server's ACK and FIN can appear merged together.



The state transitions you're observing, from the client's point of view: SYN-SENT → ESTABLISHED → FIN-WAIT-1 → FIN-WAIT-2 → TIME-WAIT.






Common Pitfalls





  • Thinking of the handshake as "one shake." It's actually three packets. Count SYN, SYN-ACK, and ACK separately.


  • Trying to memorize absolute seq/ack values. The ISN is random. What matters is the relationship (ack = peer's seq + 1). tcpdump shows relative sequence numbers (starting at 1) by default, which makes the capture easier to read.


  • Reading [.] as "nothing." [.] is an ACK-only packet. It appears as the third packet of the handshake and as acknowledgments of data.


  • Confusing FIN with RST. FIN is a polite close; RST is an abort (nobody listening, connection refused, and so on). How a connection is closed determines which one you see.


  • Capture timing. Start tcpdump before connecting. Get the order wrong and you'll miss the SYN.


  • Half-close. Closing happens per direction. One side sending its FIN doesn't stop the other side from sending more data.






Cleanup






CODE
sudo containerlab destroy -t tcp-07.clab.yml --cleanup






If you used labctl.sh run tcp-07, the script runs destroy for you at the end.






Check Your Understanding




  1. Why does establishing a TCP connection take three packets? What would be missing with just one?

  2. What is the relationship between the SYN-ACK's ack and the client SYN's seq? Why +1?

  3. What do tcpdump's [S], [S.], [.], [F.], and [R] each represent?

  4. Why does closing a connection take four packets (or close to it)? What is a half-close?

  5. What's the difference between a FIN close and an RST close?

  6. In the capture, after which packet does the client enter ESTABLISHED?






References











Verified Run Log (2026-07-05)



This lab has been confirmed reproducible on real hardware.



Environment:




  • Ubuntu 26.04 LTS (kernel 7.0.0-27-generic, x86_64)

  • Docker 29.1.3

  • containerlab 0.77.0

  • client / server: nicolaka/netshoot:latest



Running PATH="/tmp/pl-shim:$PATH" ./scripts/labctl.sh run tcp-07 performed deploy → verify → destroy, and verification.json returned "status": "verified".






Keeping up with environment drift (a fix this verification required)





  • netshoot's netcat had been swapped out. The current nicolaka/netshoot no longer ships nmap's ncat (with --exec); it ships OpenBSD netcat (nc) and socat instead. OpenBSD nc has no --exec/-e, so the echo server is now started with socat TCP-LISTEN:8080,reuseaddr,fork EXEC:/bin/cat, and the client send switched to nc -w2 (both . If these labs are useful to you, please ⭐ star the repo on GitHub — it genuinely helps others find the project.



    Next up, Lab 08 breaks this connection on purpose: retransmission, windowing, and how TCP recovers from loss.

    Vollständiger Original-Bericht
    Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
    ↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
Apple brings a fully revamped Siri built on Google's Gemini, but not to the EU
1 Quelle
Jensen Huang puts Trump on speakerphone onstage to announce robots won’t take over the world
1 Quelle
September Patch Tuesday: 963 CVEs, 2 exploited flaws, 1 message
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten One TCP Connection, From SYN to FIN: Capture the Whole Lifecycle in tcpdump

Thematisch verwandte Begriffe: Connection, From, Capture, Whole · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...