DPKT Packet Manipulation Library
DPKT is a fast, simple Python library for creating and parsing network packets, providing definitions for many common TCP/IP protocols like Ethernet, IP, TCP, and UDP. Its current stable version is 1.9.8, with releases occurring semi-regularly, focusing on bug fixes, protocol updates, and performance improvements.
Warnings
- breaking DPKT made a significant transition from Python 2 to Python 3. Versions prior to 1.9.0 were primarily Python 2 focused (with 1.8.8 being the last Python 2 'legacy stable' release). Later versions, starting from 1.9.0, fully support Python 3 and dropped Python 2.6 support in 1.9.3.
- gotcha When constructing `dpkt.ip.IP` packets, earlier versions had a bug where serializing the packet would change its length attribute. This could lead to incorrect packet sizes or truncated data during transmission or re-parsing.
- gotcha Prior to version 1.9.8, there were known endianness issues in handling PCAPNG files, Loopback captures, and IEEE 802.11 Beacon frames, which could lead to incorrect parsing or data interpretation for these specific formats.
- deprecated A performance regression was introduced in `dpkt` version 1.9.7 which significantly slowed down packet processing for certain workloads.
- gotcha Older versions of `dpkt.pcap.Reader` might not correctly handle PCAPNG files (newer pcap format). Version 1.9.7 introduced `dpkt.pcap.UniversalReader` to automatically detect and parse both PCAP and PCAPNG formats.
Install
-
pip install dpkt
Imports
- pcap
from dpkt import pcap
- ethernet
from dpkt import ethernet
- ip
from dpkt import ip
- tcp
from dpkt import tcp
- udp
from dpkt import udp
- utils
from dpkt import utils
Quickstart
import dpkt
import datetime
import os
# Helper functions for printing (usually from dpkt.utils)
def mac_to_str(buf):
return ':'.join('%02x' % b for b in buf)
def ip_to_str(buf):
return '.'.join('%d' % b for b in buf)
# 1. Create a dummy pcap file for demonstration
output_pcap_file = 'test.pcap'
with open(output_pcap_file, 'wb') as f:
writer = dpkt.pcap.Writer(f, linktype=dpkt.pcap.DLT_EN10MB)
# Create a simple Ethernet frame with an IP packet and ICMP payload
eth = dpkt.ethernet.Ethernet()
eth.src = b'\x00\x11\x22\x33\x44\x55'
eth.dst = b'\xAA\xBB\xCC\xDD\xEE\xFF'
eth.type = dpkt.ethernet.ETH_TYPE_IP
ip = dpkt.ip.IP()
ip.src = b'\x7f\x00\x00\x01' # 127.0.0.1
ip.dst = b'\x7f\x00\x00\x02' # 127.0.0.2
ip.p = dpkt.ip.IP_PROTO_ICMP # Example protocol
ip.data = dpkt.icmp.ICMP(type=dpkt.icmp.ICMP_ECHO, data=dpkt.icmp.ICMP.Echo(id=1, seq=1, data=b'Hello DPKT!'))
# dpkt handles length calculation usually, but sometimes explicit setting helps
ip.len = len(ip.data) + ip.__hdr_len__
eth.data = ip
# Write the packet to the pcap file with current timestamp
writer.writepkt(eth.pack(), ts=datetime.datetime.now().timestamp())
print(f"Created '{output_pcap_file}' with a dummy packet.")
# 2. Now, read and parse the pcap file
try:
with open(output_pcap_file, 'rb') as f:
# Use dpkt.pcap.UniversalReader(f) for auto-detection of PCAP/PCAPNG
pcap_reader = dpkt.pcap.Reader(f)
print(f"\nParsing packets from '{output_pcap_file}':")
for timestamp, buf in pcap_reader:
print(f'Timestamp: {str(datetime.datetime.fromtimestamp(timestamp))}')
eth = dpkt.ethernet.Ethernet(buf)
print(f' Ethernet Frame: {mac_to_str(eth.src)} -> {mac_to_str(eth.dst)}')
if eth.type == dpkt.ethernet.ETH_TYPE_IP:
ip_packet = eth.data
print(f' IP Packet: {ip_to_str(ip_packet.src)} -> {ip_to_str(ip_packet.dst)}, Proto: {ip_packet.p}')
if ip_packet.p == dpkt.ip.IP_PROTO_ICMP:
icmp_packet = ip_packet.data
if isinstance(icmp_packet, dpkt.icmp.ICMP) and isinstance(icmp_packet.data, dpkt.icmp.ICMP.Echo):
print(f' ICMP Echo Request: ID={icmp_packet.data.id}, Seq={icmp_packet.data.seq}, Data={repr(icmp_packet.data.data)}')
else:
print(f' Non-IP Packet (Type: {hex(eth.type)})')
finally:
# Clean up the dummy file
if os.path.exists(output_pcap_file):
os.remove(output_pcap_file)
print(f"\nCleaned up '{output_pcap_file}'.")