TCP Traffic Monitoring with tcpdump Sockets: Advanced Topics

 

TCP Traffic Monitoring with tcpdump
Chapter 61 ยท Sockets: Advanced Topics โ€” Part 1 of 3
๐Ÿ”Ž tcpdump basics
๐Ÿ“ˆ TCP segment analysis
๐Ÿ”— Wireshark overview

What is tcpdump?

When you write a TCP/IP application, you often need to see exactly what packets are flying over the network โ€” are they arriving? In what order? With what flags? That is exactly what tcpdump does. It is a command-line tool that captures network packets and prints them in a human-readable format so you can debug connections, verify handshakes, and spot problems.

Wireshark is the graphical alternative that does the same job but with a point-and-click interface. It was formerly called Ethereal and is available at http://www.wireshark.org/.

Key Terms in This Chapter

tcpdump Wireshark TCP segment SYN / FIN / ACK Sequence number Three-way handshake Connection termination TCP flags

๐Ÿ“‹ tcpdump Output Format โ€” What Each Field Means

For every TCP segment captured, tcpdump prints one line like this:

src > dst: flags data-seqno ack window urg <options>

Here is what each part means:

Field Meaning Example
src Source IP address and port pukaki.60391
dst Destination IP address and port tekapo.55555
flags TCP control bits โ€” S=SYN, F=FIN, P=PSH, R=RST, E=ECE, C=CWR, dot(.)=ACK only S or P or .
data-seqno Range of sequence numbers covered by bytes in this packet. By default shown relative to the first byte seen; use -S for absolute values. 1:17(16) means bytes 1โ€“17, size 16
ack Next sequence number expected from the other side ack 17
window Receive buffer space available โ€” tells sender how much data can be sent before blocking win 5840
urg Offset of urgent data in the segment (rare) urg 0
options TCP option fields (timestamps, MSS, etc.) omitted in examples

Note: src, dst, and flags are always shown. The rest appear only when relevant to that segment.

โš™ Running tcpdump โ€” Useful Options

The most common invocation to filter by port number:

$ tcpdump -t -N 'port 55555'

Option breakdown:

  • -t โ€” suppress timestamp, keeps output clean
  • -N โ€” show hostnames without the domain part (e.g., pukaki instead of pukaki.example.com)
  • 'port 55555' โ€” Berkeley Packet Filter (BPF) expression that captures only traffic on port 55555
  • -S โ€” show absolute sequence numbers instead of relative ones

You can also capture on a specific interface:

$ sudo tcpdump -i eth0 -t -N 'port 55555'

๐Ÿค TCP Three-Way Handshake โ€” How a Connection Starts

Before any data flows, TCP performs a three-way handshake to establish the connection. Here is what tcpdump shows for that exchange between client pukaki and server tekapo on port 55555:

IP pukaki.60391 > tekapo.55555: S 3412991013:3412991013(0) win 5840
IP tekapo.55555 > pukaki.60391: S 1149562427:1149562427(0) ack 3412991014 win 5792
IP pukaki.60391 > tekapo.55555: . ack 1 win 5840

CLIENT (pukaki) SERVER (tekapo)

SYN (seq=3412991013)

โ–บ

โ—„

SYN+ACK

ACK

โ–บ
โœ… Connection Established

Notice:

  • Line 1: Client sends S (SYN) with its initial sequence number, zero data bytes (0).
  • Line 2: Server replies with S (SYN) + acknowledges client’s seq (ack 3412991014 = client seq + 1).
  • Line 3: Client sends a plain ACK (.). The sequence numbers are now shown relative โ€” ack 1 means the first expected byte from server.

๐Ÿ“ค Data Transfer Phase

After the handshake, the client sends two messages (16 bytes, then 32 bytes). The server replies with 4-byte acknowledgements each time:

IP pukaki.60391 > tekapo.55555: P 1:17(16) ack 1 win 5840
IP tekapo.55555 > pukaki.60391: . ack 17 win 1448
IP tekapo.55555 > pukaki.60391: P 1:5(4) ack 17 win 1448
IP pukaki.60391 > tekapo.55555: . ack 5 win 5840
IP pukaki.60391 > tekapo.55555: P 17:49(32) ack 5 win 5840
IP tekapo.55555 > pukaki.60391: . ack 49 win 1448
IP tekapo.55555 > pukaki.60391: P 5:9(4) ack 49 win 1448
IP pukaki.60391 > tekapo.55555: . ack 9 win 5840

How to read P 1:17(16):

  • P โ€” PSH flag is set, meaning the sender wants the receiver to deliver the data immediately to the application.
  • 1:17 โ€” Sequence numbers 1 through 17 (relative).
  • (16) โ€” 16 bytes of payload.

Each data segment gets an ACK (.) from the other side confirming receipt. The server’s receive window shrinks from 5792 to 1448 as it processes data.

๐Ÿšซ TCP Connection Termination โ€” The Four-Way Close

Closing a TCP connection takes four segments, not three, because each side independently closes its half:

IP pukaki.60391 > tekapo.55555: F 49:49(0) ack 9 win 5840
IP tekapo.55555 > pukaki.60391: . ack 50 win 1448
IP tekapo.55555 > pukaki.60391: F 9:9(0) ack 50 win 1448
IP pukaki.60391 > tekapo.55555: . ack 10 win 5840

CLIENT SERVER
FIN (seq=49)

โ–บ
โ—„

ACK (ack 50)

โ—„

FIN (seq=9)

ACK (ack 10)

โ–บ
๐Ÿ”’ Connection Closed

Notice the client FIN goes from seq 49 to 49 with zero bytes โ€” the FIN itself consumes one sequence number. So the server ACKs with ack 50. Similarly, the server FIN at seq 9 gets ACKed by client as ack 10.

๐Ÿ’ป Practical Code: Simple TCP Server to Test with tcpdump

Here is a minimal TCP server in C. Run it, then use tcpdump to watch the handshake:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

#define PORT 55555
#define BUF_SIZE 256

int main(void)
{
    int sfd, cfd;
    struct sockaddr_in addr;
    char buf[BUF_SIZE];
    ssize_t nr;

    /* 1. Create TCP socket */
    sfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sfd == -1) { perror("socket"); exit(EXIT_FAILURE); }

    /* 2. Bind to port 55555 on all interfaces */
    memset(&addr, 0, sizeof(addr));
    addr.sin_family      = AF_INET;
    addr.sin_port        = htons(PORT);
    addr.sin_addr.s_addr = htonl(INADDR_ANY);

    if (bind(sfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
        perror("bind"); exit(EXIT_FAILURE);
    }

    /* 3. Listen for connections */
    if (listen(sfd, 5) == -1) { perror("listen"); exit(EXIT_FAILURE); }

    printf("Server listening on port %d\n", PORT);
    printf("In another terminal run:\n");
    printf("  sudo tcpdump -t -N 'port %d'\n\n", PORT);

    /* 4. Accept one connection */
    cfd = accept(sfd, NULL, NULL);
    if (cfd == -1) { perror("accept"); exit(EXIT_FAILURE); }
    printf("Client connected!\n");

    /* 5. Echo data back */
    while ((nr = read(cfd, buf, BUF_SIZE)) > 0) {
        printf("Received %zd bytes\n", nr);
        if (write(cfd, buf, nr) != nr) {
            fprintf(stderr, "Partial write\n");
        }
    }

    close(cfd);
    close(sfd);
    return 0;
}

Compile and run:

$ gcc -o tcp_server tcp_server.c
$ ./tcp_server

In another terminal, start tcpdump before connecting a client:

$ sudo tcpdump -t -N 'port 55555'

Connect with netcat to generate traffic:

$ echo "Hello World" | nc localhost 55555

You will see SYN, SYN-ACK, ACK, PSH, FIN segments in tcpdump output.

๐ŸŽ“ Interview Questions

Q1. What does the dot (.) in tcpdump flags mean?

The dot means only the ACK bit is set in the TCP segment โ€” no SYN, no FIN, no data push. It is a pure acknowledgement.

Q2. In the tcpdump line P 1:17(16), what does each part represent?

P = PSH flag; 1:17 = relative sequence range; (16) = 16 bytes of data payload.

Q3. Why does a TCP connection need three segments to open but four to close?

Opening is done together โ€” the server combines SYN and ACK in one segment. Closing requires each side to separately send a FIN and receive an ACK because the two halves of the connection are independent; the server may still have data to send after the client closes its half.

Q4. What does the -S option in tcpdump do?

By default, tcpdump shows relative sequence numbers starting from 0. The -S option forces absolute sequence numbers as negotiated in the SYN segment.

Q5. What is the difference between tcpdump and Wireshark?

Both capture and decode network packets. tcpdump is a command-line tool suited for servers and automation. Wireshark provides a graphical interface with colour-coded protocol dissection and interactive filtering, which is better for interactive debugging on a desktop.

Q6. What does the win field in tcpdump output represent?

It shows the receive window size โ€” the number of bytes the sender of that segment is willing to accept before getting an acknowledgement. It is how TCP implements flow control.

Q7. What BPF filter would you use to capture only HTTP traffic?

$ sudo tcpdump -t -N 'tcp port 80'

You can also combine filters: 'host 192.168.1.5 and port 80'.

Continue Learning
Next: Socket Options โ€” setsockopt and getsockopt

Part 2: Socket Options โ†’ Part 3: SO_REUSEADDR โ†’

Leave a Reply

Your email address will not be published. Required fields are marked *