EZ LearnEZ Learn
Courses
EZ Board
Dashboard
All articles
python-for-cyber-securitypythondpktpacket-parsing

Parsing Packets with DPKT

A captured packet is a parcel wrapped several times over: Ethernet around IP around TCP around the payload. Reading it means unwrapping one layer at a time, carefully enough to survive a messy real capture.

Ashish Revar18 October 20266 min read2 views
1 video lesson 6:24 total
Sign in to track your progress

Video lesson

The last article read a packet as a single block of bytes. This one opens it up: every packet is several messages nested inside one another, and reading it means unwrapping them in order, outside first.

Analogy: The parcel inside the parcel

A captured packet is a parcel wrapped several times over. The outermost wrapping is the Ethernet frame, addressed between two machines on the same local network. Inside it sits an IP packet, addressed between the true source and destination across the internet. Inside that sits a TCP segment or UDP datagram, which names the ports. And inside that, at last, is the payload: the HTTP request, the DNS query, the actual message.

Ethernet frame (MAC to MAC)IP packet (source IP to destination IP)TCP segment (source port to destination port)Payload: the HTTP request, DNS query, or message
Figure 4.2. Packet encapsulation. Each layer wraps the one inside it. DPKT unwraps them from the outside in: Ethernet, then IP, then TCP, then the payload.

Unwrapping a TCP packet

parse_tcp_packets.py

# parse_tcp_packets.py
import dpkt
import socket
from open_capture import read_packets

for ts, raw in read_packets("capture.pcap"):
    try:
        eth = dpkt.ethernet.Ethernet(raw)
        if not isinstance(eth.data, dpkt.ip.IP):
            continue
        ip = eth.data
        src_ip = socket.inet_ntoa(ip.src)
        dst_ip = socket.inet_ntoa(ip.dst)
        if not isinstance(ip.data, dpkt.tcp.TCP):
            continue
        tcp = ip.data
        print(f"{src_ip}:{tcp.sport} -> {dst_ip}:{tcp.dport}  "
              f"payload={len(tcp.data)} bytes")
    except (dpkt.dpkt.NeedData, dpkt.dpkt.UnpackError):
        continue

Sample output

10.0.0.9:52100 -> 93.184.216.34:443  payload=517 bytes
10.0.0.9:52100 -> 93.184.216.34:443  payload=1460 bytes
10.0.0.9:52100 -> 93.184.216.34:443  payload=0 bytes

Each line is one packet, unwrapped three layers deep: the source and destination addresses from the IP layer, the ports from the TCP layer, and the payload size. A payload of 0 bytes is usually a pure acknowledgement, a packet carrying control information but no data, which is normal and common.

Two habits that keep the script alive

This capture also contained an ARP frame and one deliberately truncated, unreadable frame mixed in among the TCP traffic, the kind of thing every real capture eventually has. Run against it, parse_tcp_packets.py printed exactly the three lines above and nothing else: the ARP frame and the broken one were silently skipped, not crashed on.

isinstance checks

isinstance(eth.data, dpkt.ip.IP) confirms a frame actually carries an IP packet, and isinstance(ip.data, dpkt.tcp.TCP) confirms that IP packet carries TCP, before either is read. A capture contains other traffic, ARP among it, that would raise an error if forced into the wrong shape.

try/except around the whole loop

A real capture almost always holds a few malformed or truncated packets. A script that stops on the first one is useless against a file with thousands. Catching dpkt.dpkt.NeedData and dpkt.dpkt.UnpackError around the loop body lets the script log or skip the bad packet and keep going.

socket.inet_ntoa() converts the raw packed bytes of an address into the familiar dotted form, the same call you have already seen in earlier units for turning bytes into a readable IP address.

Try it yourself: See the hardening earn its keep

Delete the try/except from parse_tcp_packets.py and run it again against a capture that contains even one ARP frame. It will crash on ip.src, since an ARP packet, held in eth.data, has no such attribute. Put the try/except back, and the same capture runs clean. Seeing the crash once is the fastest way to believe the hardening is not boilerplate.

Check your understanding

Question 1: Using the parcel analogy, name the four layers DPKT unwraps from a captured packet, from outside in, and state what each layer addresses.

Ethernet frame, addressed by MAC address between two machines on the same local network; IP packet, addressed by IP address between the true source and destination; TCP segment (or UDP datagram), which names the source and destination ports; and the payload, the actual message such as an HTTP request.

Question 2: Why does parse_tcp_packets.py check isinstance before reading each layer, and why is the try/except around the loop essential for a real capture?

The isinstance checks confirm a frame genuinely carries an IP packet, and that the IP packet genuinely carries TCP, before the code reads fields that only exist on those types; without the check, non-IP or non-TCP traffic such as ARP would raise an error. The try/except is essential because a real capture almost always contains a few malformed or truncated packets, and without it the whole script would stop at the first one instead of processing the thousands of packets that follow.

Question 3: What does a TCP payload of 0 bytes usually mean, and is it something to worry about?

It usually means the packet is a pure acknowledgement, carrying TCP control information but no application data. It is normal and common, not a sign of anything wrong on its own.

Key takeaway: Key takeaway

A packet is unwrapped from the outside in: Ethernet, then IP, then TCP, then the payload. Guard every layer with an isinstance check before reading it, and wrap the whole loop in a try/except, because a real capture will contain traffic that does not fit the shape you are expecting.

Assessments

Unit Assessment

Network Traffic Analysis with Python

20 questions30 minPass: 60%

Start exam →

Comprehensive Assessment

Python for Cyber Security: Complete Assessment

100 questions120 minPass: 60%

Start final exam →

Related to this topic

Continue learning

Reference material

Cheatsheet

Python for Cyber Security — Cheatsheet

v1.0

Open resource

MCQ Bank

Python for Cyber Security — MCQ Bank

v1.0

Open resource

Question Bank

Python for Cyber Security — Question Bank

v1.0

Open resource

eBook

Python for Cyber Security — eBook

v1.0

Open resource

Discussion

Loading comments…
More articlesTest your knowledge
EZ MentorAI · Free

Parsing Packets with DPKT

Hi! I'm EZ Mentor

Your AI tutor for
Parsing Packets with DPKT

Sign in to ask, it's free.

EZ Mentor is AI-powered · Answers may not be perfect · 10 free questions / day

EZ LearnEZ Learn

Structured learning across Reverse Engineering, Cloud Security, and Research Methodology, plus games and practice tools in EZ Arena. Free, and open to anyone.

EZ Learn

  • Courses
  • EZ Articles
  • EZ Watch
  • EZ Talks
  • EZ Bytes
  • Cyber Hygiene

EZ Library

  • All Resources
  • eBooks & PDFs
  • Question Banks
  • MCQ Banks
  • Cheatsheets

EZ Exams

  • All Exams
  • REMA
  • Cloud Security
  • Research Methodology
  • Python for Cyber Security
  • Cyber Law & IPR
  • Community
  • EZ Board

EZ Arena

  • EZ Games
  • Live Quiz
  • ML Challenges
  • दिशा - Hygiene
  • सजग - Awareness
  • अभ्यास - Practice

Platform

  • About
  • Contact
  • Terms of Use
  • Disclaimer
  • Verify Certificate
  • Events

© 2026 EZ Learn by EpochZero. Educational content for learning purposes.

Platform Lead: Ashish Revar