tcpdump

@amitmund September 11, 2026

Linux tcpdump — Complete Learning Notes & Output Guide

tcpdump is the premier command-line packet analyzer for Linux and Unix-like systems. Powered by the libpcap library, it captures, filters, and decodes raw network frames from Layer 2 (Data Link) through Layer 7 (Application) directly at the kernel network interface boundary using in-kernel Berkeley Packet Filters (BPF).


1. What is tcpdump?

tcpdump attaches to network interfaces via Linux AF_PACKET raw sockets. When packets traverse the network device driver, the kernel's BPF engine evaluates filtering expressions immediately—copying only matching packets to user space while discarding non-matching frames with minimal overhead.

It answers critical networking and infrastructure questions:

  • Are packets physically arriving at the host interface, or are they being blocked upstream?
  • Why is a TCP 3-way handshake failing (e.g., silent drops vs. active RST rejections)?
  • What is the exact payload, latency, and status code of DNS, DHCP, or ICMP traffic?
  • Is traffic failing due to Path MTU Discovery (PMTUD) black holes or packet fragmentation?
  • Which client IP is generating connection floods or malformed headers?

2. Installation & Availability

tcpdump is available across standard distribution package repositories:

Debian / Ubuntu

sudo apt update
sudo apt install tcpdump

RHEL / Rocky / AlmaLinux / CentOS

sudo dnf install tcpdump

Arch Linux

sudo pacman -S tcpdump

Verify installation:

tcpdump --version


3. Basic Syntax & Core Option Flags

sudo tcpdump [options] [BPF_filter_expression]

Essential Command Flags

Flag Purpose Operational Significance
-i <iface> Listen on a specific interface (e.g., eth0, lo, any). any captures traffic across all active interfaces simultaneously.
-n Do not resolve host addresses to domain names. Prevents DNS latency and extra network traffic during capture.
-nn Do not resolve host addresses or port names (e.g., :80 instead of http). Mandatory in production to avoid reverse-DNS lookup delays.
**-v / -vv / -vvv** Increase output verbosity (decodes IP TTL, ID, options, TCP flags). -vv prints full protocol headers and options.
-c <count> Exit after capturing $N$ matching packets. Prevents runaway terminal scrolling and buffer saturation.
-s <snaplen> Packet capture slice length in bytes (-s 0 captures full packet). Modern tcpdump defaults to 262144 bytes (full frame).
-w <file.pcap> Write raw packet data to a file instead of parsing to stdout. Produces standard PCAP files viewable in Wireshark.
-r <file.pcap> Read and parse packets from a saved PCAP file. Allows offline analysis with different BPF filters.
-e Print Layer 2 link-level headers (source/destination MAC addresses, VLAN tags). Essential for debugging ARP, VLAN trunking, and L2 switches.
**-X / -XX** Print packet payload in both Hex and ASCII (-XX includes link header). Inspects unencrypted application payloads (HTTP, DNS, SMTP).
-S Print absolute TCP sequence numbers instead of relative numbers. Necessary for correlating packet traces with application logs.
-q Quiet/Quick output; prints brief protocol information. Reduces line length on high-volume traffic streams.
-tttt Print timestamps in human-readable YYYY-MM-DD HH:MM:SS.frac format. Critical for correlating packet captures with system logs.

Standard Production Command Recipes

# 1. Capture live traffic without DNS/port resolution on eth0
sudo tcpdump -nn -i eth0

# 2. Capture full packets on port 443 with human-readable timestamps
sudo tcpdump -nn -tttt -i eth0 port 443

# 3. Capture all traffic across all interfaces and write to a PCAP file
sudo tcpdump -nn -i any -s 0 -w /tmp/capture.pcap

# 4. Inspect raw packet payloads (Hex + ASCII) for port 80
sudo tcpdump -nn -X -i eth0 port 80


4. Anatomy of Default TCP Output

Capturing a standard TCP connection flow with -nn:

sudo tcpdump -nn -i eth0 port 5432

Raw Output Example (TCP Data Transfer)

07:22:15.102345 IP 192.168.1.50.54210 > 10.0.0.5.5432: Flags [P.], seq 1420:1870, ack 8912, win 502, options [nop,nop,TS val 1420512 ecr 8912401], length 450
07:22:15.103120 IP 10.0.0.5.5432 > 192.168.1.50.54210: Flags [.], ack 1870, win 1024, options [nop,nop,TS val 8912410 ecr 1420512], length 0


5. Breakdown of Every Output Heading & Field

+--------------+----+--------------------+---+--------------------+------------+----------------+----------+---------+--------------------+------------+
| Timestamp    | Net| Source IP.Port     | > | Destination IP.Port| Flags      | Sequence Range | Ack Num  | Window  | TCP Options        | Payload Len|
+--------------+----+--------------------+---+--------------------+------------+----------------+----------+---------+--------------------+------------+
| 07:22:15.102 | IP | 192.168.1.50.54210 | > | 10.0.0.5.5432      | Flags [P.] | seq 1420:1870  | ack 8912 | win 502 | options [nop,...]  | length 450 |
+--------------+----+--------------------+---+--------------------+------------+----------------+----------+---------+--------------------+------------+

5.1 Timestamp (07:22:15.102345)

  • Format: HH:MM:SS.frac (microsecond or nanosecond resolution).
  • Meaning: The exact time the kernel network subsystem timestamped the packet upon driver receipt or transmit enqueue.

5.2 Network Protocol (IP)

  • Values: IP (IPv4), IP6 (IPv6), ARP, RARP.

5.3 Source & Destination (192.168.1.50.54210 > 10.0.0.5.5432)

  • Format: <Source_IP>.<Source_Port> > <Dest_IP>.<Dest_Port>
  • Meaning: Direction of frame transit indicated by the > arrow. In this case, client ephemeral port 54210 is sending data to PostgreSQL port 5432.

5.4 Flags [P.] (TCP Control Flags)

TCP header control bits are enclosed inside square brackets:

Flag Symbol TCP Flag Name Meaning & Diagnostic Role
[S] SYN Connection synchronization request (first step of 3-way handshake).
[S.] SYN-ACK Server acknowledgment and reciprocal sync (second step of handshake).
[.] ACK Acknowledgment packet carrying no control flags.
**[P] / [P.]** PUSH Push flag set; instruct the receiving OS to push data to the application immediately.
**[F] / [F.]** FIN Clean connection teardown initiation from the sender.
**[R] / [R.]** RST Connection reset; packet rejected, port closed, or connection abruptly aborted.
[U] URG Urgent pointer field is significant.
[E] ECE ECN-Echo (Explicit Congestion Notification).
[W] CWR Congestion Window Reduced.

5.5 seq 1420:1870 (Sequence Number Range)

  • Format: first_byte_seq:last_byte_seq
  • Meaning: Byte offset indexes within the TCP stream. 1420:1870 means this packet carries 450 bytes of payload starting at byte 1420 up to byte 1869.
  • Relative vs. Absolute: By default, tcpdump tracks relative offsets starting at 1 for readability. Use -S to view the raw 32-bit random hardware sequence numbers.

5.6 ack 8912 (Acknowledgment Number)

  • Meaning: The next expected sequence number the sender expects to receive from the remote peer. Confirms all bytes up to 8911 have been received.

5.7 win 502 (TCP Window Size)

  • Meaning: The current receive window buffer space (in bytes or window-scaled units) available on the sender.
  • Troubleshooting Significance: If this drops to win 0 (ZeroWindow), the host is out of socket buffer memory and cannot accept more data, halting transmission.

5.8 options [...] (TCP Options)

  • nop: No-Operation (padding to align headers on 32-bit/4-byte boundaries).
  • TS val ... ecr ...: TCP Timestamps: val is the sender timestamp; ecr (echo reply) is the latest timestamp received from the remote peer (used to calculate Round Trip Time).
  • mss <size>: Maximum Segment Size announced during the SYN handshake.
  • sackOK: Selective Acknowledgment supported.
  • wscale <factor>: Window scale multiplier.

5.9 length 450 (Payload Length)

  • Meaning: The size of the Layer 4 application payload in bytes (excluding IP and TCP header overhead). A pure ACK packet has length 0.

6. Anatomy of UDP, ICMP, & ARP Output

UDP DNS Query Example

07:30:01.124510 IP 192.168.1.50.48912 > 1.1.1.1.53: 45210+ A? api.github.com. (32)
07:30:01.145120 IP 1.1.1.1.53 > 192.168.1.50.48912: 45210 1/0/0 A 140.82.121.4 (48)

  • 45210+: DNS Transaction ID. The + indicates the Recursion Desired flag is set.
  • A? api.github.com.: Record type requested (A IPv4 record) and the queried FQDN.
  • 1/0/0: Number of Answer records (1), Authority records (0), and Additional records (0).
  • A 140.82.121.4: The resolved IP returned by the nameserver.

ICMP Ping & Unreachable Example

07:31:05.102340 IP 192.168.1.50 > 8.8.8.8: ICMP echo request, id 1420, seq 1, length 64
07:31:05.118940 IP 8.8.8.8 > 192.168.1.50: ICMP echo reply, id 1420, seq 1, length 64
07:31:06.102450 IP 192.168.1.1 > 192.168.1.50: ICMP 10.200.1.5 unreachable - host unreachable, length 36

  • Shows ICMP types (echo request, echo reply, destination unreachable).

Layer 2 ARP Request/Reply Example (-e)

07:32:00.102450 52:54:00:12:34:56 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 192.168.1.1 tell 192.168.1.50, length 28
07:32:00.103110 00:1c:73:a1:b2:00 > 52:54:00:12:34:56, ethertype ARP (0x0806), length 60: Reply 192.168.1.1 is-at 00:1c:73:a1:b2:00, length 46

  • Shows hardware source and destination MACs, EtherType (0x0806), and the IP-to-MAC resolution handshake.

7. BPF (Berkeley Packet Filter) Expressions Cheat Sheet

BPF expressions filter traffic in the kernel before copying data to user space.

sudo tcpdump [options] '<expression>'

1. Primitive Qualifiers

Qualifier Type Keywords Examples
Type host, net, port, portrange host 192.168.1.1, net 10.0.0.0/16, port 443, portrange 8000-8080
Direction src, dst, src or dst, src and dst src host 10.0.0.5, dst port 53
Protocol ip, ip6, arp, ether, tcp, udp, icmp ip proto \tcp, ether proto 0x8100 (VLAN)

2. Logical Operators

  • Concatenation: and (or &&)
  • Alternation: or (or ||)
  • Negation: not (or !)
# Capture traffic between host A and host B excluding SSH
sudo tcpdump -nn host 192.168.1.50 and host 10.0.0.5 and not port 22

3. Advanced Byte-Level BPF Slicing

You can inspect raw packet header offsets using proto[offset:size]:

# Capture only TCP SYN packets (Flags byte at offset 13; SYN bit is 0x02)
sudo tcpdump -nn "tcp[tcpflags] & (tcp-syn) != 0 and tcp[tcpflags] & (tcp-ack) == 0"

# Capture only TCP RST packets
sudo tcpdump -nn "tcp[tcpflags] & (tcp-rst) != 0"

# Capture ICMP Destination Unreachable packets (ICMP Type byte at offset 0 == 3)
sudo tcpdump -nn "icmp[0] == 3"

# Capture IP packets with TTL <= 5 (Traceroute packets)
sudo tcpdump -nn "ip[8] <= 5"


8. PCAP Capture, Buffer Handling, & Ring Rotation

On high-throughput production servers, capturing to a single continuous file can fill the filesystem or crash user space due to memory consumption. Use ring buffer rotation:

sudo tcpdump -nn -i eth0 -s 0 -w /var/log/capture_%Y-%m-%d_%H:%M:%S.pcap \
  -G 3600 \
  -C 500 \
  -W 10

Flags Explained:

  • -w <template>: Destination path. Accepts strftime format codes when -G is enabled.
  • -G 3600: Rotate the capture file every 3600 seconds (1 hour).
  • -C 500: Rotate the file if it reaches 500 Megabytes ($500 \times 10^6$ bytes) before the time interval expires.
  • -W 10: Maintain a rolling window of at most 10 files, deleting the oldest upon the 11th rotation.

9. Real-World Troubleshooting Scenarios

Scenario A: Diagnosing Handshake Rejections (Connection Refused)

A microservice logs Connection refused when connecting to 10.0.0.5:5432.

Capture the handshake attempt:

sudo tcpdump -nn -i any host 10.0.0.5 and port 5432

Output:

14:10:01.100120 IP 192.168.1.50.41200 > 10.0.0.5.5432: Flags [S], seq 104250, win 64240, length 0
14:10:01.100450 IP 10.0.0.5.5432 > 192.168.1.50.41200: Flags [R.], seq 0, ack 104251, win 0, length 0

Diagnosis:

  1. The client sent a SYN (Flags [S]).
  2. The server responded immediately with RST-ACK (Flags [R.]).
  3. Root Cause: The target server is reachable, and intermediate firewalls are permitting traffic; however, no process is listening on port 5432 on the destination host, or the database service crashed.

Scenario B: Diagnosing Path MTU Discovery Black Holes

Users can load small web pages, but downloading large files or completing TLS handshakes hangs indefinitely.

Trace ICMP Fragmentation Needed messages:

sudo tcpdump -nn -i eth0 "icmp[0] == 3 and icmp[1] == 4"

Or inspect outgoing DF (Don't Fragment) packets:

sudo tcpdump -nnvv -i eth0 "ip[6] & 0x40 != 0"

Output:

15:02:12.102340 IP 192.168.1.1 > 192.168.1.50: ICMP 10.0.0.5 unreachable - need to frag (mtu 1420), length 556

Diagnosis: An intermediate VPN tunnel or overlay network has an MTU of 1420 bytes. The sender is transmitting 1500-byte frames with the DF (Don't Fragment) bit set. The intermediate router drops the frame and emits an ICMP "need to frag" message. If an aggressive upstream firewall blocks this ICMP message, the connection suffers a PMTUD Black Hole and hangs.


Scenario C: Investigating Packet Drops by tcpdump vs. Kernel

When stopping tcpdump with Ctrl-C, it prints an exit summary:

^C
125042 packets captured
125042 packets received by filter
14210 packets dropped by kernel

Breakdown of the 3 Counters:

  • packets captured: Total packets processed and emitted to stdout or written to the PCAP file.
  • packets received by filter: Total packets that matched the BPF filter expression and were queued for user space.
  • packets dropped by kernel: Packet loss in the capture pipeline. The packets matched the filter, but the kernel socket buffer allocated to tcpdump (AF_PACKET socket ring buffer) overflowed before tcpdump could read them into user space.

How to Prevent Drops by Kernel:

  1. Increase the socket receive buffer size with -B:
sudo tcpdump -i eth0 -B 4096 -w /tmp/large.pcap

(-B 4096 allocates a 4 MB buffer instead of the default 2 MB). 2. Avoid decoding packets to stdout (use -w to write directly to a fast NVMe/tmpfs volume). 3. Do not run packet dissection flags (-X, -vv) on live traffic processing tens of thousands of packets per second.


10. Important Interview Questions & Answers

Q: How does Berkeley Packet Filter (BPF) prevent performance degradation when filtering traffic on high-throughput interfaces?

Answer: BPF runs inside the Linux kernel execution context. When a network driver receives a packet, the BPF bytecode program is evaluated directly in-kernel via the JIT (Just-In-Time) compiler against the packet descriptor. If the packet does not match the expression (e.g., traffic is port 80, but filter specifies port 443), the kernel immediately discards the frame from the capture path. The packet is never copied across the kernel-user space memory boundary into tcpdump's socket buffer, avoiding costly context switches and memory copies.

Q: Why does tcpdump sometimes display outgoing TCP packets with lengths of 16KB to 64KB, exceeding the physical interface MTU (1500 bytes)?

Answer: This occurs because of TCP Segmentation Offload (TSO) or Generic Segmentation Offload (GSO). To conserve host CPU cycles, the Linux network stack constructs large multi-segment buffers (up to 64 KB) and hands them directly to the physical Network Interface Card (NIC). The NIC hardware ASIC is responsible for slicing the large segment into standard 1500-byte wire frames. Because tcpdump captures outgoing packets via an AF_PACKET socket before the buffer reaches the NIC hardware driver, it sees the unsegmented 64 KB memory buffer.

Q: What is Promiscuous Mode, and does tcpdump always enable it?

Answer: By default, a NIC only passes frames to the OS if the destination MAC matches the interface's own MAC, the broadcast MAC (ff:ff:ff:ff:ff:ff), or a joined multicast group. Promiscuous Mode instructs the physical NIC controller to disable hardware MAC filtering, passing all frames observed on the physical medium up to the operating system. tcpdump enables promiscuous mode by default upon launch and disables it upon termination. You can explicitly prevent this using the -p flag (tcpdump -p -i eth0), which is necessary when capturing on heavily loaded shared ports to avoid capturing neighbors' unicast traffic.


0 Likes
3 Views
0 Comments

Filters

No filters available for this view.

Reset All