how tcp connection works
Published: 2021-09-11 12:48:54

This post describes how to see TCP connection establishment and termination as packets using tcpdump on linux.

Preparing
Install following commands on your linux.

 - tcpdump 
 - nc 
 - telnet 
 - netstat

## See TCP connection establishment

## 1. start TCP server

Start TCP server using nc command with l,k option.
$ nc -lk 12345

[Open a Listening port on Linux](https://www.howtouselinux.com/post/linux-command-open-a-port-on-linux)

Open another terminal and verify 12345 port is listening using netstat command.
$ netstat -anp | grep 12345
tcp  0  0  0.0.0.0:12345  0.0.0.0:*  LISTEN  <PID>/nc             

## 2. start TCP client and establish connection

Start TCP client using telnet to establish TCP connection with TCP server of step 1.
$ telnet 127.0.0.1 12345
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Open another terminal and verify nc process and telnet are establishing connection using netstat command.

[5 ways to Check a remote port is open in Linux](https://www.howtouselinux.com/post/linux-5-ways-to-check-a-remote-port-is-open)

$ netstat -anp | grep 12345
tcp  0  0 0.0.0.0:12345     0.0.0.0:*        LISTEN      <PID>/nc
tcp  0  0 127.0.0.1:<port>  127.0.0.1:12345  ESTABLISHED <PID>/telnet
tcp  0  0 127.0.0.1:12345   127.0.0.1:<port> ESTABLISHED <PID>/nc 
Terminate TCP client with type "Ctrl+[" and "quit" on telnet. Then Connection is close.
$ telnet 127.0.0.1 12345
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
^]
telnet> quit
Connection closed.
$ 
It's ready to see TCP connection establishment with tcpdump.

## 3. See TCP 3-Way Handshake as TCP connection establishment

Verify TCP server that start at step 1 listen 12345 port.
$ netstat -anp | grep 12345
tcp  0  0  0.0.0.0:12345  0.0.0.0:*  LISTEN  <PID>/nc             
Perform tcpdump with specify local interface and port 12345 as follows.
$ sudo tcpdump -i lo -nnn port 12345
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 65535 bytes
Start TCP client using telnet to establish TCP connection with TCP server of step 1.
$ telnet 127.0.0.1 12345
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.

[Tcpdump: Filter Packets By Port](https://www.howtouselinux.com/post/tcpdump-ports)
Verify tcpdump output as follows.
HH:mm:ss.SSSSSS IP 127.0.0.1.<port> > 127.0.0.1.12345:  Flags [S], seq ...
HH:mm:ss.SSSSSS IP 127.0.0.1.12345  > 127.0.0.1.<port>: Flags [S.], seq ...
HH:mm:ss.SSSSSS IP 127.0.0.1.<port> > 127.0.0.1.12345:  Flags [.], ack ...
The format is as follows
timestamp IP source IP.port destination > IP.port: flags
First line means a SYN packet as "[S]" flag that telnet sent to TCP server.
Second line means SYN + ACK packet as "[S.]" flag that TCP server sent to telnet.
Third line means ACK packet as "[.]" flag that TCP server sent to telnet.
[Exploring Tcpdump Filters with Examples](https://www.howtouselinux.com/post/tcpdump-filters)
[Understanding TCP Socket With Examples](https://www.howtouselinux.com/post/tcp-socket)

# See TCP connection termination
Open another terminal and verify nc process and telnet are establishing connection using netstat command.
$ netstat -anp | grep 12345
tcp  0  0 0.0.0.0:12345     0.0.0.0:*        LISTEN      <PID>/nc
tcp  0  0 127.0.0.1:<port>  127.0.0.1:12345  ESTABLISHED <PID>/telnet
tcp  0  0 127.0.0.1:12345   127.0.0.1:<port> ESTABLISHED <PID>/nc 

## 3. See terminate TCP connection establishment

Keep tcpdump, and terminate TCP client with type "Ctrl+[" and "quit" on telnet. Then Connection is close.
$ telnet 127.0.0.1 12345
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
^]
telnet> quit
Connection closed.
$ 
Verify tcpdump output as follows.

[Understanding TCP Flags SYN ACK RST FIN URG PSH](https://www.howtouselinux.com/post/tcp-flags)
HH:mm:ss.SSSSSS IP 127.0.0.1.<port> > 127.0.0.1.12345:  Flags [F.], seq 1,
HH:mm:ss.SSSSSS IP 127.0.0.1.12345  > 127.0.0.1.<port>: Flags [F.], seq 1,
HH:mm:ss.SSSSSS IP 127.0.0.1.<port> > 127.0.0.1.12345:  Flags [.], ack 2,
First line means a FIN packet as "[F]" flag that telnet sent to TCP server.
Second line means FIN + ACK packet as "[F.]" flag that TCP server sent to telnet.
Third line means ACK packet as "[.]" flag that TCP server sent to telnet.

[Tcpdump: Filter Packets with Tcp Flags](https://www.howtouselinux.com/post/tcpdump-capture-packets-with-tcp-flags)
[Understanding TCP Connection with Examples](https://www.howtouselinux.com/post/tcp-connection)
[Understanding TCP Sequence Number with Examples](https://www.howtouselinux.com/post/understanding-tcp-sequence-number)