Network · Packet Captures

Reading PCAPs

A packet capture is just bytes. The skill is reading those bytes as the OSI stack: Ethernet, IP, TCP, then application. Once you can do that, you can answer almost any "what happened on the wire?" question.

A pcap is the file format produced by libpcap and consumed by tcpdump, Wireshark, tshark, Zeek, Suricata, and roughly every other network tool worth using. The file is a flat sequence of captured frames: timestamp, length, raw bytes. Each frame is what your network card saw on the wire (or wireless air), exactly as it arrived.

Reading a pcap is a stack-walking exercise. Take the bytes, identify the Ethernet header at the front, find the IP header inside that, find the TCP/UDP header inside that, find the application payload inside that. The layers are nested like envelopes inside envelopes.

Capturing: tcpdump basics

Before reading a pcap, you have to make one. tcpdump is the canonical command-line capture tool. The basic invocations every network analyst memorizes:

# capture all traffic on interface eth0 to file, with packet content sudo tcpdump -i eth0 -w capture.pcap # capture only what you want with a BPF filter (more on this below) sudo tcpdump -i eth0 -w out.pcap "host 10.0.0.50 and tcp port 443" # read a saved pcap, summarize each packet (one line per packet) tcpdump -r capture.pcap -n # read a pcap with verbose output AND the raw hex+ASCII dump tcpdump -r capture.pcap -n -X -vvv # rotating capture — 100MB per file, keep last 10 files sudo tcpdump -i eth0 -w cap.pcap -C 100 -W 10

Two flags you'll always want: -n disables DNS reverse lookups (massive speedup; you don't want capture analysis to chase DNS), and -w writes to a file. -r reads one back.

BPF: the filter language

BPF (Berkeley Packet Filter) is a tiny domain-specific language for selecting packets. It's compiled into kernel bytecode for speed — the kernel evaluates the filter on every packet at line rate. Mastering BPF is half of capture work.

FilterMeaning
host 192.0.2.10Source OR destination is that IP
src host 192.0.2.10Source IP only
dst host 192.0.2.10Destination IP only
port 443Source OR destination port 443
tcp port 443TCP only, port 443 either side
net 10.0.0.0/24Any host in that subnet
tcp[tcpflags] & (tcp-syn) != 0TCP SYN packets — very useful for spotting scans
icmpAll ICMP (pings, errors)
not arpEverything except ARP — reduces noise
host A and (port 80 or port 443)Combined — HTTP/HTTPS to host A

BPF filters apply at capture time. Wireshark's display filters (covered in the next page) apply at display time and use a different syntax. Don't confuse them.

Anatomy of one packet

An HTTP GET request travelling over IPv4 + TCP + Ethernet is a single frame on the wire with four nested headers.

Layer 2 · Ethernet 14 bytes. src MAC | dst MAC | EtherType. EtherType 0x0800 = IPv4 next. The MACs are LAN-local — they change at every router hop.
Layer 3 · IPv4 20 bytes (no options). Source IP, destination IP, TTL, protocol number (6 = TCP, 17 = UDP, 1 = ICMP). The IPs are end-to-end — preserved across the entire path.
Layer 4 · TCP 20 bytes (no options). Source port, destination port, sequence number, ack number, flags (SYN, ACK, FIN, RST, PSH, URG), window size, checksum.
Layer 7 · HTTP (or whatever) The payload. GET /index.html HTTP/1.1\r\nHost: example.com\r\n.... For TLS this is encrypted; you see ClientHello/ServerHello and ciphertext.

A real capture, narrated

Here's tcpdump output of a TCP three-way handshake followed by a quick HTTP GET. Reading skills first; we'll deconstruct line by line.

# tcpdump -r demo.pcap -n -tttt 2025-03-14 23:47:00.123456 IP 10.0.0.50.51382 > 93.184.216.34.80: Flags [S], seq 1872334801, win 65535, options [mss 1460,sackOK,TS val 4123 ecr 0,nop,wscale 7], length 0 2025-03-14 23:47:00.142891 IP 93.184.216.34.80 > 10.0.0.50.51382: Flags [S.], seq 2891734028, ack 1872334802, win 65535, options [mss 1460,sackOK,TS val 8210 ecr 4123,nop,wscale 7], length 0 2025-03-14 23:47:00.143012 IP 10.0.0.50.51382 > 93.184.216.34.80: Flags [.], ack 1, win 514, options [nop,nop,TS val 4124 ecr 8210], length 0 2025-03-14 23:47:00.143508 IP 10.0.0.50.51382 > 93.184.216.34.80: Flags [P.], seq 1:78, ack 1, win 514, options [nop,nop,TS val 4124 ecr 8210], length 77: HTTP: GET / HTTP/1.1 2025-03-14 23:47:00.162847 IP 93.184.216.34.80 > 10.0.0.50.51382: Flags [P.], seq 1:1349, ack 78, win 514, options [nop,nop,TS val 8220 ecr 4124], length 1348: HTTP: HTTP/1.1 200 OK

Five lines tell the entire story:

What captures tell you

tshark: tcpdump with display filters

tshark is the command-line version of Wireshark. It uses Wireshark's dissector library, so it knows hundreds of protocols natively — HTTP, DNS, SMB, RDP, Kerberos, MQTT, you name it.

# extract just HTTP request URIs from a pcap tshark -r web.pcap -Y "http.request" -T fields -e ip.src -e http.host -e http.request.uri # show DNS queries and responses with timestamps tshark -r dns.pcap -Y "dns" -T fields -e frame.time -e dns.qry.name -e dns.a # list every distinct IP that talked on this capture tshark -r big.pcap -T fields -e ip.src -e ip.dst | sort -u # find TLS handshakes and the SNI hostname (which destination did the client want?) tshark -r tls.pcap -Y "tls.handshake.type == 1" -T fields -e ip.dst -e tls.handshake.extensions_server_name

For incident response, tshark is usually faster than opening Wireshark — you can pipeline it with grep/awk/sort/uniq to answer specific questions in seconds.

Why captures are both gold and poison

Captures contain everything. Cleartext passwords, session cookies, internal IPs, internal hostnames, file contents, photos, voice. A pcap of your network for an hour is a confidentiality grenade. Treat raw captures as top-of-house sensitive: encrypted at rest, access-controlled, retention-limited. Never email a pcap. Never put one in a public bug tracker.

For sharing with vendors or external researchers, tcprewrite can anonymize IPs and MACs in a pcap. There are also tools (pcapfix, tcpdump --print-data) that let you strip payload bytes while preserving headers — useful when you only need metadata.

The point

Reading a pcap is the network analyst's deepest skill. The format is simple — nested headers — but interpreting what the packets mean requires fluency in TCP behavior, common protocol patterns, and operational baselines. The fastest way to develop the skill is to capture your own traffic during normal use, then read it back. You'll see the same patterns hundreds of times before you have to recognize the abnormal one in production.

Next page: how to do the same investigations in a graphical tool — Wireshark's actual UI, display filters, and the "Follow Stream" feature that turns a pile of TCP segments back into the conversation you can read.

References

Formatted in APA 7.

  1. The Tcpdump Group. (2024). Tcpdump & libpcap. https://www.tcpdump.org/
  2. Wireshark Foundation. (2024). tshark — the Wireshark command-line tool. https://www.wireshark.org/docs/man-pages/tshark.html
  3. Hartpence, B. (2011). Packet guide to core network protocols. O'Reilly Media.
  4. Sanders, C. (2017). Practical packet analysis: Using Wireshark to solve real-world network problems (3rd ed.). No Starch Press.